<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Interactive BOM for KiCAD</title>
  <style type="text/css">
:root {
  --pcb-edge-color: black;
  --pad-color: #878787;
  --pad-color-highlight: #D04040;
  --pin1-outline-color: #ffb629;
  --pin1-outline-color-highlight: #b4ff03;
  --silkscreen-edge-color: #aa4;
  --silkscreen-polygon-color: #4aa;
  --silkscreen-text-color: #4aa;
  --fabrication-edge-color: #907651;
  --fabrication-polygon-color: #907651;
  --fabrication-text-color: #a27c24;
  --track-color: #def5f1;
  --track-color-highlight: #D04040;
  --zone-color: #def5f1;
  --zone-color-highlight: #d0404080;
}

html, body {
  margin: 0px;
  height: 100%;
  font-family: Verdana, sans-serif;
}

.dark.topmostdiv {
  --pcb-edge-color: #eee;
  --pad-color: #808080;
  --pin1-outline-color: #ffa800;
  --pin1-outline-color-highlight: #ccff00;
  --track-color: #42524f;
  --zone-color: #42524f;
  background-color: #252c30;
  color: #eee;
}

button {
  background-color: #eee;
  border: 1px solid #888;
  color: black;
  height: 44px;
  width: 44px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 14px;
  font-weight: bolder;
}

.dark button {
  /* This will be inverted */
  background-color: #c3b7b5;
}

button.depressed {
  background-color: #0a0;
  color: white;
}

.dark button.depressed {
  /* This will be inverted */
  background-color: #b3b;
}

button:focus {
  outline: 0;
}

button#tb-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.32 290.12h5.82M1.32 291.45h5.82' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 292.5v4.23M.26 292.63H8.2' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='1.35' y='295.73'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
}

button#lr-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.06 290.12H3.7m-2.64 1.33H3.7m-2.64 1.32H3.7m-2.64 1.3H3.7m-2.64 1.33H3.7' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 288.8v7.94m0-4.11h3.96' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='5.11' y='291.96'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
}

button#bom-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)' fill='none' stroke='%23000' stroke-width='.4'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' stroke-linejoin='round'/%3E%3Cpath d='M1.59 290.12h5.29M1.59 291.45h5.33M1.59 292.75h5.33M1.59 294.09h5.33M1.59 295.41h5.33'/%3E%3C/g%3E%3C/svg%3E");
}

button#bom-grouped-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m4 0h5m4 0h3M6.1 22h3m3.9 0h5m4 0h4m-16-8h4m4 0h4'/%3E%3Cpath stroke-linecap='null' d='M5 17.5h22M5 26.6h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
}

button#bom-ungrouped-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m-4 8h3m-3 8h4'/%3E%3Cpath stroke-linecap='null' d='M5 13.5h22m-22 8h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
}

button#bom-netlist-btn {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='none' stroke='%23000' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-width='2' d='M6 26l6-6v-8m13.8-6.3l-6 6v8'/%3E%3Ccircle cx='11.8' cy='9.5' r='2.8' stroke-width='2'/%3E%3Ccircle cx='19.8' cy='22.8' r='2.8' stroke-width='2'/%3E%3C/g%3E%3C/svg%3E");
}

button#copy {
  background-image: url("data:image/svg+xml,%3Csvg height='48' viewBox='0 0 48 48' width='48' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h48v48h-48z' fill='none'/%3E%3Cpath d='M32 2h-24c-2.21 0-4 1.79-4 4v28h4v-28h24v-4zm6 8h-22c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h22c2.21 0 4-1.79 4-4v-28c0-2.21-1.79-4-4-4zm0 32h-22v-28h22v28z'/%3E%3C/svg%3E");
  background-position: 6px 6px;
  background-repeat: no-repeat;
  background-size: 26px 26px;
  border-radius: 6px;
  height: 40px;
  width: 40px;
  margin: 10px 5px;
}

button#copy:active {
    box-shadow: inset 0px 0px 5px #6c6c6c;
}

textarea.clipboard-temp {
  position: fixed;
  top: 0;
  left: 0;
  width: 2em;
  height: 2em;
  padding: 0;
  border: None;
  outline: None;
  box-shadow: None;
  background: transparent;
}

.left-most-button {
  border-right: 0;
  border-top-left-radius: 6px;
  border-bottom-left-radius: 6px;
}

.middle-button {
  border-right: 0;
}

.right-most-button {
  border-top-right-radius: 6px;
  border-bottom-right-radius: 6px;
}

.button-container {
  font-size: 0;
  margin: 10px 10px 10px 0px;
}

.dark .button-container {
  filter: invert(1);
}

.button-container button {
  background-size: 32px 32px;
  background-position: 5px 5px;
  background-repeat: no-repeat;
}

@media print {
  .hideonprint {
    display: none;
  }
}

canvas {
  cursor: crosshair;
}

canvas:active {
  cursor: grabbing;
}

.fileinfo {
  width: 100%;
  max-width: 1000px;
  border: none;
  padding: 5px;
}

.fileinfo .title {
  font-size: 20pt;
  font-weight: bold;
}

.fileinfo td {
  overflow: hidden;
  white-space: nowrap;
  max-width: 1px;
  width: 50%;
  text-overflow: ellipsis;
}

.bom {
  border-collapse: collapse;
  font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
  font-size: 10pt;
  table-layout: fixed;
  width: 100%;
  margin-top: 1px;
}

.bom th, .bom td {
  border: 1px solid black;
  padding: 5px;
  word-wrap: break-word;
  text-align: center;
  position: relative;
}

.dark .bom th, .dark .bom td {
  border: 1px solid #777;
}

.bom th {
  background-color: #CCCCCC;
  background-clip: padding-box;
}

.dark .bom th {
  background-color: #3b4749;
}

.bom tr.highlighted:nth-child(n) {
  background-color: #cfc;
}

.dark .bom tr.highlighted:nth-child(n) {
  background-color: #226022;
}

.bom tr:nth-child(even) {
  background-color: #f2f2f2;
}

.dark .bom tr:nth-child(even) {
  background-color: #313b40;
}

.bom tr {
  transition: background-color 0.2s;
}

.bom .numCol {
  width: 25px;
}

.bom .Description {
  width: 10%;
}

.bom .Part {
  width: 10%;
}

.bom .Value {
  width: 15%;
}

.bom .Quantity {
  width: 65px;
}

.bom th .sortmark {
  position: absolute;
  right: 1px;
  top: 1px;
  margin-top: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent transparent #221 transparent;
  transform-origin: 50% 85%;
  transition: opacity 0.2s, transform 0.4s;
}

.dark .bom th .sortmark {
  filter: invert(1);
}

.bom th .sortmark.none {
  opacity: 0;
}

.bom th .sortmark.desc {
  transform: rotate(180deg);
}

.bom th:hover .sortmark.none {
  opacity: 0.5;
}

.bom .bom-checkbox {
  width: 30px;
  position: relative;
  user-select: none;
  -moz-user-select: none;
}

.bom .bom-checkbox:before {
  content: "";
  position: absolute;
  border-width: 15px;
  border-style: solid;
  border-color: #51829f transparent transparent transparent;
  visibility: hidden;
  top: -15px;
}

.bom .bom-checkbox:after {
  content: "Double click to set/unset all";
  position: absolute;
  color: white;
  top: -35px;
  left: -26px;
  background: #51829f;
  padding: 5px 15px;
  border-radius: 8px;
  white-space: nowrap;
  visibility: hidden;
}

.bom .bom-checkbox:hover:before, .bom .bom-checkbox:hover:after {
  visibility: visible;
  transition: visibility 0.2s linear 1s;
}

.split {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  overflow-y: auto;
  overflow-x: hidden;
  background-color: inherit;
}

.split.split-horizontal, .gutter.gutter-horizontal {
  height: 100%;
  float: left;
}

.gutter {
  background-color: #ddd;
  background-repeat: no-repeat;
  background-position: 50%;
  transition: background-color 0.3s;
}

.dark .gutter {
  background-color: #777;
}

.gutter.gutter-horizontal {
  background-image: url('');
  cursor: ew-resize;
  width: 5px;
}

.gutter.gutter-vertical {
  background-image: url('');
  cursor: ns-resize;
  height: 5px;
}

.searchbox {
  float: left;
  height: 40px;
  margin: 10px 5px;
  padding: 12px 32px;
  font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
  font-size: 18px;
  box-sizing: border-box;
  border: 1px solid #888;
  border-radius: 6px;
  outline: none;
  background-color: #eee;
  transition: background-color 0.2s, border 0.2s;
  background-image: url('');
  background-position: 10px 10px;
  background-repeat: no-repeat;
}

.dark .searchbox {
  background-color: #111;
  color: #eee;
}

.searchbox::placeholder {
  color: #ccc;
}

.dark .searchbox::placeholder {
  color: #666;
}

.filter {
  width: calc(60% - 64px);
}

.reflookup {
  width: calc(40% - 10px);
}

input[type=text]:focus {
  background-color: white;
  border: 1px solid #333;
}

.dark input[type=text]:focus {
  background-color: #333;
  border: 1px solid #ccc;
}

mark.highlight {
  background-color: #5050ff;
  color: #fff;
  padding: 2px;
  border-radius: 6px;
}

.dark mark.highlight {
  background-color: #76a6da;
  color: #111;
}

.menubtn {
  background-color: white;
  border: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A");
  background-position: center;
  background-repeat: no-repeat;
}

.statsbtn {
  background-color: white;
  border: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 9.52 9.53'%3E%3Cg fill='none' stroke-width='.53'%3E%3Cpath d='M.8.8h7.4v7.67H.8z' stroke='%23666'/%3E%3Cpath d='M8.73 1.06V9H1.06' stroke='%23ccc'/%3E%3Cpath d='M1.85 2.12H3.7M4.5 2.12h1.06M6.09 2.12h1.05M1.85 3.44H3.7M4.5 3.44h1.06M6.09 3.44h1.05M1.85 5.3h1.33M1.85 6.88h1.32M3.97 6.88H6.6M3.97 5.3h3.17' stroke='%23000'/%3E%3C/g%3E%3C/svg%3E");
  background-position: center;
  background-repeat: no-repeat;
}

.iobtn {
  background-color: white;
  border: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M3 33v-7l6.8-7h16.5l6.7 7v7H3zM3.2 26H33M21 9l5-5.9 5 6h-2.5V15h-5V9H21zm-4.9 0l-5 6-5-6h2.5V3h5v6h2.5z'/%3E%3Cpath fill='none' stroke='%23000' d='M6.1 29.5H10'/%3E%3C/svg%3E");
  background-position: center;
  background-repeat: no-repeat;
}

.dark .statsbtn, .dark .savebtn, .dark .menubtn, .dark .iobtn {
  filter: invert(1);
}

.flexbox {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.savebtn {
  background-color: #d6d6d6;
  width: auto;
  height: 30px;
  flex-grow: 1;
  margin: 5px;
  border-radius: 4px;
}

.savebtn:active {
  background-color: #0a0;
  color: white;
}

.dark .savebtn:active {
  /* This will be inverted */
  background-color: #b3b;
}

.stats {
  border-collapse: collapse;
  font-size: 12pt;
  table-layout: fixed;
  width: 100%;
  min-width: 450px;
}

.dark .stats td {
  border: 1px solid #bbb;
}

.stats td {
  border: 1px solid black;
  padding: 5px;
  word-wrap: break-word;
  text-align: center;
  position: relative;
}

#checkbox-stats div {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

#checkbox-stats .bar {
  background-color: rgba(28, 251, 0, 0.6);
}

.menu {
  position: relative;
  display: inline-block;
  margin: 10px 10px 10px 0px;
}

.menu-content {
  display: none;
  position: absolute;
  background-color: white;
  right: 0;
  min-width: 300px;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 100;
  padding: 8px;
}

.dark .menu-content {
  background-color: #111;
}

.menu:hover .menu-content {
  display: block;
}

.menu:hover .menubtn, .menu:hover .iobtn, .menu:hover .statsbtn {
  background-color: #eee;
}

.menu-label {
  display: inline-block;
  padding: 8px;
  border: 1px solid #ccc;
  border-top: 0;
  width: calc(100% - 18px);
}

.menu-label-top {
  border-top: 1px solid #ccc;
}

.menu-textbox {
  float: left;
  height: 24px;
  margin: 10px 5px;
  padding: 5px 5px;
  font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
  font-size: 14px;
  box-sizing: border-box;
  border: 1px solid #888;
  border-radius: 4px;
  outline: none;
  background-color: #eee;
  transition: background-color 0.2s, border 0.2s;
  width: calc(100% - 10px);
}

.menu-textbox.invalid, .dark .menu-textbox.invalid {
  color: red;
}

.dark .menu-textbox {
  background-color: #222;
  color: #eee;
}

.topmostdiv {
  width: 100%;
  height: 100%;
  background-color: white;
  transition: background-color 0.3s;
}

#top {
  height: 78px;
  border-bottom: 2px solid black;
}

.dark #top {
  border-bottom: 2px solid #ccc;
}

#dbg {
  display: block;
}

::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: #aaa;
}

::-webkit-scrollbar-thumb {
  background: #666;
  border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
  background: #555;
}

.slider {
  -webkit-appearance: none;
  width: 100%;
  margin: 3px 0;
  padding: 0;
  outline: none;
  opacity: 0.7;
  -webkit-transition: .2s;
  transition: opacity .2s;
  border-radius: 3px;
}

.slider:hover {
  opacity: 1;
}

.slider:focus {
  outline: none;
}

.slider::-webkit-slider-runnable-track {
  -webkit-appearance: none;
  width: 100%;
  height: 8px;
  background: #d3d3d3;
  border-radius: 3px;
  border: none;
}

.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #0a0;
  cursor: pointer;
  margin-top: -4px;
}

.dark .slider::-webkit-slider-thumb {
  background: #3d3;
}

.slider::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #0a0;
  cursor: pointer;
}

.slider::-moz-range-track {
  height: 8px;
  background: #d3d3d3;
  border-radius: 3px;
}

.dark .slider::-moz-range-thumb {
  background: #3d3;
}

.slider::-ms-track {
  width: 100%;
  height: 8px;
  border-width: 3px 0;
  background: transparent;
  border-color: transparent;
  color: transparent;
  transition: opacity .2s;
}

.slider::-ms-fill-lower {
  background: #d3d3d3;
  border: none;
  border-radius: 3px;
}

.slider::-ms-fill-upper {
  background: #d3d3d3;
  border: none;
  border-radius: 3px;
}

.slider::-ms-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #0a0;
  cursor: pointer;
  margin: 0;
}

.shameless-plug {
  font-size: 0.8em;
  text-align: center;
  display: block;
}

a {
  color: #0278a4;
}

.dark a {
  color: #00b9fd;
}

#frontcanvas, #backcanvas {
    touch-action: none;
}

  </style>
  <script type="text/javascript" >
///////////////////////////////////////////////
/*
  Split.js - v1.3.5
  MIT License
  https://github.com/nathancahill/Split.js
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}});

///////////////////////////////////////////////

///////////////////////////////////////////////
// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
// This work is free. You can redistribute it and/or modify it
// under the terms of the WTFPL, Version 2
// For more information see LICENSE.txt or http://www.wtfpl.net/
//
// For more information, the home page:
// http://pieroxy.net/blog/pages/lz-string/testing.html
//
// LZ-based compression algorithm, version 1.4.4
var LZString=function(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t<o.length;t++)i[o][o.charAt(t)]=t}return i[o][n]}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",o.charAt(n))})},_decompress:function(i,n,t){var r,e,a,s,p,u,l,f=[],c=4,d=4,h=3,v="",g=[],m={val:t(0),position:n,index:1};for(r=0;r<3;r+=1)f[r]=r;for(a=0,p=Math.pow(2,2),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString});
///////////////////////////////////////////////

///////////////////////////////////////////////
/*!
 * PEP v0.4.3 | https://github.com/jquery/PEP
 * Copyright jQuery Foundation and other contributors | http://jquery.org/license
 */
!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.PointerEventsPolyfill=b()}(this,function(){"use strict";function a(a,b){b=b||Object.create(null);var c=document.createEvent("Event");c.initEvent(a,b.bubbles||!1,b.cancelable||!1);
for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0;
var f=0;return f=b.pressure&&c.buttons?b.pressure:c.buttons?.5:0,c.x=c.clientX,c.y=c.clientY,c.pointerId=b.pointerId||0,c.width=b.width||0,c.height=b.height||0,c.pressure=f,c.tiltX=b.tiltX||0,c.tiltY=b.tiltY||0,c.twist=b.twist||0,c.tangentialPressure=b.tangentialPressure||0,c.pointerType=b.pointerType||"",c.hwTimestamp=b.hwTimestamp||0,c.isPrimary=b.isPrimary||!1,c}function b(){this.array=[],this.size=0}function c(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),A&&(this.observer=new A(this.mutationWatcher.bind(this)))}function d(a){return"body /shadow-deep/ "+e(a)}function e(a){return'[touch-action="'+a+'"]'}function f(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; }"}function g(){if(F){D.forEach(function(a){String(a)===a?(E+=e(a)+f(a)+"\n",G&&(E+=d(a)+f(a)+"\n")):(E+=a.selectors.map(e)+f(a.rule)+"\n",G&&(E+=a.selectors.map(d)+f(a.rule)+"\n"))});var a=document.createElement("style");a.textContent=E,document.head.appendChild(a)}}function h(){if(!window.PointerEvent){if(window.PointerEvent=a,window.navigator.msPointerEnabled){var b=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:b,enumerable:!0}),u.registerSource("ms",_)}else Object.defineProperty(window.navigator,"maxTouchPoints",{value:0,enumerable:!0}),u.registerSource("mouse",N),void 0!==window.ontouchstart&&u.registerSource("touch",V);u.register(document)}}function i(a){if(!u.pointermap.has(a)){var b=new Error("InvalidPointerId");throw b.name="InvalidPointerId",b}}function j(a){for(var b=a.parentNode;b&&b!==a.ownerDocument;)b=b.parentNode;if(!b){var c=new Error("InvalidStateError");throw c.name="InvalidStateError",c}}function k(a){var b=u.pointermap.get(a);return 0!==b.buttons}function l(){window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:W},releasePointerCapture:{value:X},hasPointerCapture:{value:Y}})}
var m=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],n=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],o=window.Map&&window.Map.prototype.forEach,p=o?Map:b;b.prototype={set:function(a,b){return void 0===b?this["delete"](a):(this.has(a)||this.size++,void(this.array[a]=b))},has:function(a){return void 0!==this.array[a]},"delete":function(a){this.has(a)&&(delete this.array[a],this.size--)},get:function(a){return this.array[a]},clear:function(){this.array.length=0,this.size=0},forEach:function(a,b){return this.array.forEach(function(c,d){a.call(b,c,d,this)},this)}};var q=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp"],r=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],s={pointerover:1,pointerout:1,pointerenter:1,pointerleave:1},t="undefined"!=typeof SVGElementInstance,u={pointermap:new p,eventMap:Object.create(null),captureInfo:Object.create(null),eventSources:Object.create(null),eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
b.unregister.call(b,a)},contains:function(a,b){try{return a.contains(b)}catch(c){return!1}},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.propagate(a,this.leave,!1)},enterOver:function(a){this.over(a),this.propagate(a,this.enter,!0)},eventHandler:function(a){if(!a._handledByPE){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),a._handledByPE=!0}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(b,c){this.captureInfo[c.pointerId]&&(c.relatedTarget=null);var d=new a(b,c);return c.preventDefault&&(d.preventDefault=c.preventDefault),d._target=d._target||c.target,d},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,c=Object.create(null),d=0;d<q.length;d++)b=q[d],c[b]=a[b]||r[d],!t||"target"!==b&&"relatedTarget"!==b||c[b]instanceof SVGElementInstance&&(c[b]=c[b].correspondingUseElement);return a.preventDefault&&(c.preventDefault=function(){a.preventDefault()}),c},getTarget:function(a){var b=this.captureInfo[a.pointerId];return b?a._target!==b&&a.type in s?void 0:b:a._target},propagate:function(a,b,c){for(var d=a.target,e=[];d!==document&&!d.contains(a.relatedTarget);) if(e.push(d),d=d.parentNode,!d)return;c&&e.reverse(),e.forEach(function(c){a.target=c,b.call(this,a)},this)},setCapture:function(b,c,d){this.captureInfo[b]&&this.releaseCapture(b,d),this.captureInfo[b]=c,this.implicitRelease=this.releaseCapture.bind(this,b,d),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease);var e=new a("gotpointercapture");e.pointerId=b,e._target=c,d||this.asyncDispatchEvent(e)},releaseCapture:function(b,c){var d=this.captureInfo[b];if(d){this.captureInfo[b]=void 0,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease);var e=new a("lostpointercapture");e.pointerId=b,e._target=d,c||this.asyncDispatchEvent(e)}},dispatchEvent:/*scope.external.dispatchEvent || */function(a){var b=this.getTarget(a);if(b)return b.dispatchEvent(a)},asyncDispatchEvent:function(a){requestAnimationFrame(this.dispatchEvent.bind(this,a))}};u.boundHandler=u.eventHandler.bind(u);var v={shadow:function(a){if(a)return a.shadowRoot||a.webkitShadowRoot},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);if(this.canTarget(b))return b},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d} e=this.olderShadow(e)} return f}},owner:function(a){
for(var b=a;b.parentNode;)b=b.parentNode;
return b.nodeType!==Node.DOCUMENT_NODE&&b.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);
return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}},w=Array.prototype.forEach.call.bind(Array.prototype.forEach),x=Array.prototype.map.call.bind(Array.prototype.map),y=Array.prototype.slice.call.bind(Array.prototype.slice),z=Array.prototype.filter.call.bind(Array.prototype.filter),A=window.MutationObserver||window.WebKitMutationObserver,B="[touch-action]",C={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};c.prototype={watchSubtree:function(a){
//
this.observer&&v.canTarget(a)&&this.observer.observe(a,C)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){w(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(B):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(y(b))},
installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){
var b=x(a,this.findElements,this);
return b.push(z(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}};var D=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],E="",F=window.PointerEvent||window.MSPointerEvent,G=!window.ShadowDOMPolyfill&&document.head.createShadowRoot,H=u.pointermap,I=25,J=[1,4,2,8,16],K=!1;try{K=1===new MouseEvent("test",{buttons:1}).buttons}catch(L){}
var M,N={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},lastTouches:[],
isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,d=a.clientX,e=a.clientY,f=0,g=c.length;f<g&&(b=c[f]);f++){
var h=Math.abs(d-b.x),i=Math.abs(e-b.y);if(h<=I&&i<=I)return!0}},prepareEvent:function(a){var b=u.cloneEvent(a),c=b.preventDefault;return b.preventDefault=function(){a.preventDefault(),c()},b.pointerId=this.POINTER_ID,b.isPrimary=!0,b.pointerType=this.POINTER_TYPE,b},prepareButtonsForMove:function(a,b){var c=H.get(this.POINTER_ID);
0!==b.which&&c?a.buttons=c.buttons:a.buttons=0,b.buttons=a.buttons},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);K||(c.buttons=J[c.button],b&&(c.buttons|=b.buttons),a.buttons=c.buttons),H.set(this.POINTER_ID,a),b&&0!==b.buttons?u.move(c):u.down(c)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.move(b)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);if(!K){var d=J[c.button];
c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a),
c.buttons&=~J[c.button],0===c.buttons?u.up(c):u.move(c)}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.enterOver(b)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,u.leaveOut(b)}},cancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.deactivateMouse()},deactivateMouse:function(){H["delete"](this.POINTER_ID)}},O=u.captureInfo,P=v.findTarget.bind(v),Q=v.allShadows.bind(v),R=u.pointermap,S=2500,T=200,U="touch-action",V={events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){M.enableOnSubtree(a)},unregister:function(){},elementAdded:function(a){var b=a.getAttribute(U),c=this.touchActionToScrollType(b);c&&(a._scrollType=c,u.listen(a,this.events),
Q(a).forEach(function(a){a._scrollType=c,u.listen(a,this.events)},this))},elementRemoved:function(a){a._scrollType=void 0,u.unlisten(a,this.events),
Q(a).forEach(function(a){a._scrollType=void 0,u.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(U),d=this.touchActionToScrollType(c),e=this.touchActionToScrollType(b);
d&&e?(a._scrollType=d,Q(a).forEach(function(a){a._scrollType=d},this)):e?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){
(0===R.size||1===R.size&&R.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,T)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return"touchstart"!==a&&"touchmove"!==a||(b=1),b},touchToPointer:function(a){var b=this.currentTouchEvent,c=u.cloneEvent(a),d=c.pointerId=a.identifier+2;c.target=O[d]||P(c),c.bubbles=!0,c.cancelable=!0,c.detail=this.clickCount,c.button=0,c.buttons=this.typeToButtons(b.type),c.width=2*(a.radiusX||a.webkitRadiusX||0),c.height=2*(a.radiusY||a.webkitRadiusY||0),c.pressure=a.force||a.webkitForce||.5,c.isPrimary=this.isPrimaryTouch(a),c.pointerType=this.POINTER_TYPE,
c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey;
var e=this;return c.preventDefault=function(){e.scrolling=!1,e.firstXY=null,b.preventDefault()},c},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a;for(var d,e=0;e<c.length;e++)d=c[e],b.call(this,this.touchToPointer(d))},
shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c)
b=!1;else if("XY"===c)
b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);
b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;d<e&&(c=a[d]);d++)if(c.identifier===b)return!0},
vacuumTouches:function(a){var b=a.touches;
if(R.size>=b.length){var c=[];R.forEach(function(a,d){
if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(e)}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){R.set(a.pointerId,{target:a.target,out:a,outTarget:a.target}),u.enterOver(a),u.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,c=R.get(b.pointerId);
if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e,
d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):(
b.target=e,b.relatedTarget=null,this.cancelOut(b))),c.out=b,c.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(u.up(a),u.leaveOut(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){u.cancel(a),u.leaveOut(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){R["delete"](a.pointerId),this.removePrimaryPointer(a)},
dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0];
if(this.isPrimaryTouch(c)){
var d={x:c.clientX,y:c.clientY};b.push(d);var e=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,b,d);setTimeout(e,S)}}};M=new c(V.elementAdded,V.elementRemoved,V.elementChanged,V);var W,X,Y,Z=u.pointermap,$=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,_={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var b=a;return $&&(b=u.cloneEvent(a),b.pointerType=this.POINTER_TYPES[a.pointerType]),b},cleanup:function(a){Z["delete"](a)},MSPointerDown:function(a){Z.set(a.pointerId,a);var b=this.prepareEvent(a);u.down(b)},MSPointerMove:function(a){var b=this.prepareEvent(a);u.move(b)},MSPointerUp:function(a){var b=this.prepareEvent(a);u.up(b),this.cleanup(a.pointerId)},MSPointerOut:function(a){var b=this.prepareEvent(a);u.leaveOut(b)},MSPointerOver:function(a){var b=this.prepareEvent(a);u.enterOver(b)},MSPointerCancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var b=u.makeEvent("lostpointercapture",a);u.dispatchEvent(b)},MSGotPointerCapture:function(a){var b=u.makeEvent("gotpointercapture",a);u.dispatchEvent(b)}},aa=window.navigator;aa.msPointerEnabled?(W=function(a){i(a),j(this),k(a)&&(u.setCapture(a,this,!0),this.msSetPointerCapture(a))},X=function(a){i(a),u.releaseCapture(a,!0),this.msReleasePointerCapture(a)}):(W=function(a){i(a),j(this),k(a)&&u.setCapture(a,this)},X=function(a){i(a),u.releaseCapture(a)}),Y=function(a){return!!u.captureInfo[a]},g(),h(),l();var ba={dispatcher:u,Installer:c,PointerEvent:a,PointerMap:p,targetFinding:v};return ba});

///////////////////////////////////////////////

///////////////////////////////////////////////
var config = {"dark_mode": true, "show_pads": true, "show_fabrication": false, "show_silkscreen": true, "highlight_pin1": true, "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "extra_fields": []}
///////////////////////////////////////////////

///////////////////////////////////////////////
var pcbdata = JSON.parse(LZString.decompressFromBase64("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"))
///////////////////////////////////////////////

///////////////////////////////////////////////
/* Utility functions */

var storagePrefix = 'KiCad_HTML_BOM__' + pcbdata.metadata.title + '__' +
  pcbdata.metadata.revision + '__#';
var storage;

function initStorage(key) {
  try {
    window.localStorage.getItem("blank");
    storage = window.localStorage;
  } catch (e) {
    // localStorage not available
  }
  if (!storage) {
    try {
      window.sessionStorage.getItem("blank");
      storage = window.sessionStorage;
    } catch (e) {
      // sessionStorage also not available
    }
  }
}

function readStorage(key) {
  if (storage) {
    return storage.getItem(storagePrefix + key);
  } else {
    return null;
  }
}

function writeStorage(key, value) {
  if (storage) {
    storage.setItem(storagePrefix + key, value);
  }
}

function fancyDblClickHandler(el, onsingle, ondouble) {
  return function() {
    if (el.getAttribute("data-dblclick") == null) {
      el.setAttribute("data-dblclick", 1);
      setTimeout(function() {
        if (el.getAttribute("data-dblclick") == 1) {
          onsingle();
        }
        el.removeAttribute("data-dblclick");
      }, 200);
    } else {
      el.removeAttribute("data-dblclick");
      ondouble();
    }
  }
}

function smoothScrollToRow(rowid) {
  document.getElementById(rowid).scrollIntoView({
    behavior: "smooth",
    block: "center",
    inline: "nearest"
  });
}

function focusInputField(input) {
  input.scrollIntoView(false);
  input.focus();
  input.select();
}

function copyToClipboard() {
  var text = '';
  for (var node of bomhead.childNodes[0].childNodes) {
    if (node.firstChild) {
      text = text + node.firstChild.nodeValue;
    }
    if (node != bomhead.childNodes[0].lastChild) {
      text += '\t';
    }
  }
  text += '\n';
  for (var row of bombody.childNodes) {
    for (var cell of row.childNodes) {
      for (var node of cell.childNodes) {
        if (node.nodeName == "INPUT") {
          if (node.checked) {
            text = text + '✓';
          }
        } else if (node.nodeName == "MARK") {
          text = text + node.firstChild.nodeValue;
        } else {
          text = text + node.nodeValue;
        }
      }
      if (cell != row.lastChild) {
        text += '\t';
      }
    }
    text += '\n';
  }
  var textArea = document.createElement("textarea");
  textArea.classList.add('clipboard-temp');
  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    if (document.execCommand('copy')) {
      console.log('Bom copied to clipboard.');
    }
  } catch (err) {
    console.log('Can not copy to clipboard.');
  }

  document.body.removeChild(textArea);
}

function removeGutterNode(node) {
  for (var i = 0; i < node.childNodes.length; i++) {
    if (node.childNodes[i].classList &&
      node.childNodes[i].classList.contains("gutter")) {
      node.removeChild(node.childNodes[i]);
      break;
    }
  }
}

function cleanGutters() {
  removeGutterNode(document.getElementById("bot"));
  removeGutterNode(document.getElementById("canvasdiv"));
}

var units = {
  prefixes: {
    giga: ["G", "g", "giga", "Giga", "GIGA"],
    mega: ["M", "mega", "Mega", "MEGA"],
    kilo: ["K", "k", "kilo", "Kilo", "KILO"],
    milli: ["m", "milli", "Milli", "MILLI"],
    micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ
    nano: ["N", "n", "nano", "Nano", "NANO"],
    pico: ["P", "p", "pico", "Pico", "PICO"],
  },
  unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"],
  unitsLong: [
    "OHM", "Ohm", "ohm", "ohms",
    "FARAD", "Farad", "farad",
    "HENRY", "Henry", "henry"
  ],
  getMultiplier: function(s) {
    if (this.prefixes.giga.includes(s)) return 1e9;
    if (this.prefixes.mega.includes(s)) return 1e6;
    if (this.prefixes.kilo.includes(s)) return 1e3;
    if (this.prefixes.milli.includes(s)) return 1e-3;
    if (this.prefixes.micro.includes(s)) return 1e-6;
    if (this.prefixes.nano.includes(s)) return 1e-9;
    if (this.prefixes.pico.includes(s)) return 1e-12;
    return 1;
  },
  valueRegex: null,
}

function initUtils() {
  var allPrefixes = units.prefixes.giga
                    .concat(units.prefixes.mega)
                    .concat(units.prefixes.kilo)
                    .concat(units.prefixes.milli)
                    .concat(units.prefixes.micro)
                    .concat(units.prefixes.nano)
                    .concat(units.prefixes.pico);
  var allUnits = units.unitsShort.concat(units.unitsLong);
  units.valueRegex = new RegExp("^([0-9\.]+)" +
                         "\\s*(" + allPrefixes.join("|") + ")?" +
                         "(" + allUnits.join("|") + ")?" +
                         "(\\b.*)?$", "");
  units.valueAltRegex = new RegExp("^([0-9]*)" +
                         "(" + units.unitsShort.join("|") + ")?" +
                         "([GgMmKkUuNnPp])?" +
                         "([0-9]*)" +
                         "(\\b.*)?$", "");
  for (var bom_type of ["both", "F", "B"]) {
    for (var row of pcbdata.bom[bom_type]) {
      row.push(parseValue(row[1], row[3][0][0]));
    }
  }
}

function parseValue(val, ref) {
  var inferUnit = (unit, ref) => {
    if (unit) {
      unit = unit.toLowerCase();
      if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
        unit = 'r';
      }
      unit = unit[0];
    } else {
      ref = /^([a-z]+)\d+$/i.exec(ref);
      if (ref) {
        ref = ref[1].toLowerCase();
        if (ref == "c") unit = 'f';
        else if (ref == "l") unit = 'h';
        else if (ref == "r" || ref == "rv") unit = 'r';
        else unit = null;
      }
    }
    return unit;
  };
  val = val.replace(/,/g, "");
  var match = units.valueRegex.exec(val);
  var unit;
  if (match) {
    val = parseFloat(match[1]);
    if (match[2]) {
      val = val * units.getMultiplier(match[2]);
    }
    unit = inferUnit(match[3], ref);
    if (!unit) return null;
    else return {
      val: val,
      unit: unit,
      extra: match[4],
    }
  }
  match = units.valueAltRegex.exec(val);
  if (match && (match[1] || match[4])) {
    val = parseFloat(match[1] + "." + match[4]);
    if (match[3]) {
      val = val * units.getMultiplier(match[3]);
    }
    unit = inferUnit(match[2], ref);
    if (!unit) return null;
    else return {
      val: val,
      unit: unit,
      extra: match[5],
    }
  }
  return null;
}

function valueCompare(a, b, stra, strb) {
  if (a === null && b === null) {
    // Failed to parse both values, compare them as strings.
    if (stra != strb) return stra > strb ? 1 : -1;
    else return 0;
  } else if (a === null) {
    return 1;
  } else if (b === null) {
    return -1;
  } else {
    if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
    else if (a.val != b.val) return a.val > b.val ? 1 : -1;
    else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
    else return 0;
  }
}

function validateSaveImgDimension(element) {
  var valid = false;
  var intValue = 0;
  if (/^[1-9]\d*$/.test(element.value)) {
    intValue = parseInt(element.value);
    if (intValue <= 16000) {
      valid = true;
    }
  }
  if (valid) {
    element.classList.remove("invalid");
  } else {
    element.classList.add("invalid");
  }
  return intValue;
}

function saveImage(layer) {
  var width = validateSaveImgDimension(document.getElementById("render-save-width"));
  var height = validateSaveImgDimension(document.getElementById("render-save-height"));
  var bgcolor = null;
  if (!document.getElementById("render-save-transparent").checked) {
    var style = getComputedStyle(topmostdiv);
    bgcolor = style.getPropertyValue("background-color");
  }
  if (!width || !height) return;

  // Prepare image
  var canvas = document.createElement("canvas");
  var layerdict = {
    transform: {
      x: 0,
      y: 0,
      s: 1,
      panx: 0,
      pany: 0,
      zoom: 1,
    },
    bg: canvas,
    fab: canvas,
    silk: canvas,
    highlight: canvas,
    layer: layer,
  }
  // Do the rendering
  recalcLayerScale(layerdict, width, height);
  prepareLayer(layerdict);
  clearCanvas(canvas, bgcolor);
  drawBackground(layerdict, false);
  drawHighlightsOnLayer(layerdict, false);

  // Save image
  var imgdata = canvas.toDataURL("image/png");

  var filename = pcbdata.metadata.title;
  if (pcbdata.metadata.revision) {
    filename += `.${pcbdata.metadata.revision}`;
  }
  filename += `.${layer}.png`;
  saveFile(filename, dataURLtoBlob(imgdata));
}

function saveSettings() {
  var data = {
    type: "InteractiveHtmlBom settings",
    version: 1,
    pcbmetadata: pcbdata.metadata,
    settings: settings,
  }
  var blob = new Blob([JSON.stringify(data, null, 4)], {type: "application/json"});
  saveFile(`${pcbdata.metadata.title}.settings.json`, blob);
}

function loadSettings() {
  var input = document.createElement("input");
  input.type = "file";
  input.accept = ".settings.json";
  input.onchange = function(e) {
    var file = e.target.files[0];
    var reader = new FileReader();
    reader.onload = readerEvent => {
      var content = readerEvent.target.result;
      var newSettings;
      try {
        newSettings = JSON.parse(content);
      } catch(e) {
        alert("Selected file is not InteractiveHtmlBom settings file.");
        return;
      }
      if (newSettings.type != "InteractiveHtmlBom settings") {
        alert("Selected file is not InteractiveHtmlBom settings file.");
        return;
      }
      var metadataMatches = newSettings.hasOwnProperty("pcbmetadata");
      if (metadataMatches) {
        for (var k in pcbdata.metadata) {
          if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) {
            metadataMatches = false;
          }
        }
      }
      if (!metadataMatches) {
        var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4);
        var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4);
        if (!confirm(
          `Settins file metadata does not match current metadata.\n\n` +
          `Page metadata:\n${currentMetadata}\n\n` +
          `Settings file metadata:\n${fileMetadata}\n\n` +
          `Press OK if you would like to import settings anyway.`)) {
          return;
        }
      }
      overwriteSettings(newSettings.settings);
    }
    reader.readAsText(file, 'UTF-8');
  }
  input.click();
}

function overwriteSettings(newSettings) {
  initDone = false;
  Object.assign(settings, newSettings);
  writeStorage("bomlayout", settings.bomlayout);
  writeStorage("bommode", settings.bommode);
  writeStorage("canvaslayout", settings.canvaslayout);
  writeStorage("bomCheckboxes", settings.checkboxes.join(","));
  document.getElementById("bomCheckboxes").value = settings.checkboxes.join(",");
  for (var checkbox of settings.checkboxes) {
    writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
  }
  padsVisible(settings.renderPads);
  document.getElementById("padsCheckbox").checked = settings.renderPads;
  fabricationVisible(settings.renderFabrication);
  document.getElementById("fabricationCheckbox").checked = settings.renderFabrication;
  silkscreenVisible(settings.renderSilkscreen);
  document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen;
  referencesVisible(settings.renderReferences);
  document.getElementById("referencesCheckbox").checked = settings.renderReferences;
  valuesVisible(settings.renderValues);
  document.getElementById("valuesCheckbox").checked = settings.renderValues;
  tracksVisible(settings.renderTracks);
  document.getElementById("tracksCheckbox").checked = settings.renderTracks;
  zonesVisible(settings.renderZones);
  document.getElementById("zonesCheckbox").checked = settings.renderZones;
  dnpOutline(settings.renderDnpOutline);
  document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline;
  setRedrawOnDrag(settings.redrawOnDrag);
  document.getElementById("dragCheckbox").checked = settings.redrawOnDrag;
  setDarkMode(settings.darkMode);
  document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
  setHighlightPin1(settings.highlightpin1);
  document.getElementById("highlightpin1Checkbox").checked = settings.highlightpin1;
  writeStorage("boardRotation", settings.boardRotation);
  document.getElementById("boardRotation").value = settings.boardRotation / 5;
  document.getElementById("rotationDegree").textContent = settings.boardRotation;
  initDone = true;
  prepCheckboxes();
  changeBomLayout(settings.bomlayout);
}

function saveFile(filename, blob) {
  var link = document.createElement("a");
  var objurl = URL.createObjectURL(blob);
  link.download = filename;
  link.href = objurl;
  link.click();
}

function dataURLtoBlob(dataurl) {
  var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
  while(n--){
      u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {type:mime});
}

var settings = {
  canvaslayout: "default",
  bomlayout: "default",
  bommode: "grouped",
  checkboxes: [],
  checkboxStoredRefs: {},
  darkMode: false,
  highlightpin1: false,
  redrawOnDrag: true,
  boardRotation: 0,
  renderPads: true,
  renderReferences: true,
  renderValues: true,
  renderSilkscreen: true,
  renderFabrication: true,
  renderDnpOutline: false,
  renderTracks: true,
  renderZones: true,
}

function initDefaults() {
  settings.bomlayout = readStorage("bomlayout");
  if (settings.bomlayout === null) {
    settings.bomlayout = config.bom_view;
  }
  if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) {
    settings.bomlayout = config.bom_view;
  }
  settings.bommode = readStorage("bommode");
  if (settings.bommode === null) {
    settings.bommode = "grouped";
  }
  if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) {
    settings.bommode = "grouped";
  }
  settings.canvaslayout = readStorage("canvaslayout");
  if (settings.canvaslayout === null) {
    settings.canvaslayout = config.layer_view;
  }
  var bomCheckboxes = readStorage("bomCheckboxes");
  if (bomCheckboxes === null) {
    bomCheckboxes = config.checkboxes;
  }
  settings.checkboxes = bomCheckboxes.split(",").filter((e) => e);
  document.getElementById("bomCheckboxes").value = bomCheckboxes;

  function initBooleanSetting(storageString, def, elementId, func) {
    var b = readStorage(storageString);
    if (b === null) {
      b = def;
    } else {
      b = (b == "true");
    }
    document.getElementById(elementId).checked = b;
    func(b);
  }

  initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
  initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
  initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
  initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
  initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
  if ("tracks" in pcbdata) {
    initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
    initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
  } else {
    document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
    tracksVisible(false);
    zonesVisible(false);
  }
  initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
  initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
  initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
  initBooleanSetting("highlightpin1", config.highlight_pin1, "highlightpin1Checkbox", setHighlightPin1);
  settings.boardRotation = readStorage("boardRotation");
  if (settings.boardRotation === null) {
    settings.boardRotation = config.board_rotation * 5;
  } else {
    settings.boardRotation = parseInt(settings.boardRotation);
  }
  document.getElementById("boardRotation").value = settings.boardRotation / 5;
  document.getElementById("rotationDegree").textContent = settings.boardRotation;
}

///////////////////////////////////////////////

///////////////////////////////////////////////
/* PCB rendering code */

var emptyContext2d = document.createElement("canvas").getContext("2d");

function deg2rad(deg) {
  return deg * Math.PI / 180;
}

function calcFontPoint(linepoint, text, offsetx, offsety, tilt) {
  var point = [
    linepoint[0] * text.width + offsetx,
    linepoint[1] * text.height + offsety
  ];
  // Adding half a line height here is technically a bug
  // but pcbnew currently does the same, text is slightly shifted.
  point[0] -= (point[1] + text.height * 0.5) * tilt;
  return point;
}

function drawtext(ctx, text, color, flip) {
  if ("ref" in text && !settings.renderReferences) return;
  if ("val" in text && !settings.renderValues) return;
  ctx.save();
  ctx.fillStyle = color;
  ctx.strokeStyle = color;
  ctx.lineCap = "round";
  ctx.lineJoin = "round";
  ctx.lineWidth = text.thickness;
  if (text.svgpath) {
    ctx.stroke(new Path2D(text.svgpath));
    ctx.restore();
    return;
  }
  ctx.translate(...text.pos);
  var angle = -text.angle;
  if (text.attr.includes("mirrored")) {
    ctx.scale(-1, 1);
    angle = -angle;
  }
  var tilt = 0;
  if (text.attr.includes("italic")) {
    tilt = 0.125;
  }
  var interline = (text.height * 1.5 + text.thickness) / 2;
  var txt = text.text.split("\n");
  // KiCad ignores last empty line.
  if (txt[txt.length - 1] == '') txt.pop();
  ctx.rotate(deg2rad(angle));
  for (var i in txt) {
    var offsety = (-(txt.length - 1) + i * 2) * interline + text.height / 2;
    var lineWidth = 0;
    for (var c of txt[i]) {
      if (c == '\t') {
        var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
        lineWidth += fourSpaces - lineWidth % fourSpaces;
      } else {
        lineWidth += pcbdata.font_data[c].w * text.width;
      }
    }
    var offsetx = 0;
    switch (text.horiz_justify) {
      case -1:
        // Justify left, do nothing
        break;
      case 0:
        // Justify center
        offsetx -= lineWidth / 2;
        break;
      case 1:
        // Justify right
        offsetx -= lineWidth;
        break;
    }
    for (var c of txt[i]) {
      if (c == '\t') {
        var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
        offsetx += fourSpaces - offsetx % fourSpaces;
        continue;
      }
      for (var line of pcbdata.font_data[c].l) {
        ctx.beginPath();
        ctx.moveTo(...calcFontPoint(line[0], text, offsetx, offsety, tilt));
        for (var i = 1; i < line.length; i++) {
          ctx.lineTo(...calcFontPoint(line[i], text, offsetx, offsety, tilt));
        }
        ctx.stroke();
      }
      offsetx += pcbdata.font_data[c].w * text.width;
    }
  }
  ctx.restore();
}

function drawedge(ctx, scalefactor, edge, color) {
  ctx.strokeStyle = color;
  ctx.lineWidth = Math.max(1 / scalefactor, edge.width);
  ctx.lineCap = "round";
  if (edge.svgpath) {
    ctx.stroke(new Path2D(edge.svgpath));
  } else {
    ctx.beginPath();
    if (edge.type == "segment") {
      ctx.moveTo(...edge.start);
      ctx.lineTo(...edge.end);
    }
    if (edge.type == "arc") {
      ctx.arc(
        ...edge.start,
        edge.radius,
        deg2rad(edge.startangle),
        deg2rad(edge.endangle));
    }
    if (edge.type == "circle") {
      ctx.arc(
        ...edge.start,
        edge.radius,
        0, 2 * Math.PI);
      ctx.closePath();
    }
    if (edge.type == "curve") {
      ctx.moveTo(...edge.start);
      ctx.bezierCurveTo(...edge.cpa, ...edge.cpb, ...edge.end);
    }
    ctx.stroke();
  }
}

function getChamferedRectPath(size, radius, chamfpos, chamfratio) {
  // chamfpos is a bitmask, left = 1, right = 2, bottom left = 4, bottom right = 8
  var path = new Path2D();
  var width = size[0];
  var height = size[1];
  var x = width * -0.5;
  var y = height * -0.5;
  var chamfOffset = Math.min(width, height) * chamfratio;
  path.moveTo(x, 0);
  if (chamfpos & 4) {
    path.lineTo(x, y + height - chamfOffset);
    path.lineTo(x + chamfOffset, y + height);
    path.lineTo(0, y + height);
  } else {
    path.arcTo(x, y + height, x + width, y + height, radius);
  }
  if (chamfpos & 8) {
    path.lineTo(x + width - chamfOffset, y + height);
    path.lineTo(x + width, y + height - chamfOffset);
    path.lineTo(x + width, 0);
  } else {
    path.arcTo(x + width, y + height, x + width, y, radius);
  }
  if (chamfpos & 2) {
    path.lineTo(x + width, y + chamfOffset);
    path.lineTo(x + width - chamfOffset, y);
    path.lineTo(0, y);
  } else {
    path.arcTo(x + width, y, x, y, radius);
  }
  if (chamfpos & 1) {
    path.lineTo(x + chamfOffset, y);
    path.lineTo(x, y + chamfOffset);
    path.lineTo(x, 0);
  } else {
    path.arcTo(x, y, x, y + height, radius);
  }
  path.closePath();
  return path;
}

function getOblongPath(size) {
  return getChamferedRectPath(size, Math.min(size[0], size[1]) / 2, 0, 0);
}

function getPolygonsPath(shape) {
  if (shape.path2d) {
    return shape.path2d;
  }
  if (shape.svgpath) {
    shape.path2d = new Path2D(shape.svgpath);
  } else {
    var path = new Path2D();
    for (var polygon of shape.polygons) {
      path.moveTo(...polygon[0]);
      for (var i = 1; i < polygon.length; i++) {
        path.lineTo(...polygon[i]);
      }
      path.closePath();
    }
    shape.path2d = path;
  }
  return shape.path2d;
}

function drawPolygonShape(ctx, shape, color) {
  ctx.save();
  ctx.fillStyle = color;
  if (!shape.svgpath) {
    ctx.translate(...shape.pos);
    ctx.rotate(deg2rad(-shape.angle));
  }
  ctx.fill(getPolygonsPath(shape));
  ctx.restore();
}

function drawDrawing(ctx, layer, scalefactor, drawing, color) {
  if (["segment", "arc", "circle", "curve"].includes(drawing.type)) {
    drawedge(ctx, scalefactor, drawing, color);
  } else if (drawing.type == "polygon") {
    drawPolygonShape(ctx, drawing, color);
  } else {
    drawtext(ctx, drawing, color, layer == "B");
  }
}

function getCirclePath(radius) {
  var path = new Path2D();
  path.arc(0, 0, radius, 0, 2 * Math.PI);
  path.closePath();
  return path;
}

function getCachedPadPath(pad) {
  if (!pad.path2d) {
    // if path2d is not set, build one and cache it on pad object
    if (pad.shape == "rect") {
      pad.path2d = new Path2D();
      pad.path2d.rect(...pad.size.map(c => -c * 0.5), ...pad.size);
    } else if (pad.shape == "oval") {
      pad.path2d = getOblongPath(pad.size);
    } else if (pad.shape == "circle") {
      pad.path2d = getCirclePath(pad.size[0] / 2);
    } else if (pad.shape == "roundrect") {
      pad.path2d = getChamferedRectPath(pad.size, pad.radius, 0, 0);
    } else if (pad.shape == "chamfrect") {
      pad.path2d = getChamferedRectPath(pad.size, pad.radius, pad.chamfpos, pad.chamfratio)
    } else if (pad.shape == "custom") {
      pad.path2d = getPolygonsPath(pad);
    }
  }
  return pad.path2d;
}

function drawPad(ctx, pad, color, outline, hole) {
  ctx.save();
  ctx.translate(...pad.pos);
  ctx.rotate(deg2rad(pad.angle));
  if (pad.offset) {
    ctx.translate(...pad.offset);
  }
  ctx.fillStyle = color;
  ctx.strokeStyle = color;
  var path = getCachedPadPath(pad);
  if (outline) {
    ctx.stroke(path);
  } else {
    ctx.fill(path);
  }
  if (pad.type == "th" && hole) {
    if (pad.offset) {
      ctx.translate(-pad.offset[0], -pad.offset[1]);
    }
    ctx.fillStyle = "#CCCCCC";
    if (pad.drillshape == "oblong") {
      ctx.fill(getOblongPath(pad.drillsize));
    } else {
      ctx.fill(getCirclePath(pad.drillsize[0] / 2));
    }
  }
  ctx.restore();
}

function drawModule(ctx, layer, scalefactor, module, padcolor, outlinecolor, highlight, outline) {
  if (highlight) {
    // draw bounding box
    if (module.layer == layer) {
      ctx.save();
      ctx.globalAlpha = 0.2;
      ctx.translate(...module.bbox.pos);
      ctx.rotate(deg2rad(-module.bbox.angle));
      ctx.translate(...module.bbox.relpos);
      ctx.fillStyle = padcolor;
      ctx.fillRect(0, 0, ...module.bbox.size);
      ctx.globalAlpha = 1;
      ctx.strokeStyle = padcolor;
      ctx.strokeRect(0, 0, ...module.bbox.size);
      ctx.restore();
    }
  }
  // draw drawings
  for (var drawing of module.drawings) {
    if (drawing.layer == layer) {
      drawDrawing(ctx, layer, scalefactor, drawing.drawing, padcolor);
    }
  }
  // draw pads
  if (settings.renderPads) {
    for (var pad of module.pads) {
      if (pad.layers.includes(layer)) {
        drawPad(ctx, pad, padcolor, outline, true);
        if (pad.pin1 && settings.highlightpin1) {
          drawPad(ctx, pad, outlinecolor, true, false);
        }
      }
    }
  }
}

function drawEdgeCuts(canvas, scalefactor) {
  var ctx = canvas.getContext("2d");
  var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
  for (var edge of pcbdata.edges) {
    drawedge(ctx, scalefactor, edge, edgecolor);
  }
}

function drawModules(canvas, layer, scalefactor, highlight) {
  var ctx = canvas.getContext("2d");
  ctx.lineWidth = 3 / scalefactor;
  var style = getComputedStyle(topmostdiv);
  var padcolor = style.getPropertyValue('--pad-color');
  var outlinecolor = style.getPropertyValue('--pin1-outline-color');
  if (highlight) {
    padcolor = style.getPropertyValue('--pad-color-highlight');
    outlinecolor = style.getPropertyValue('--pin1-outline-color-highlight');
  }
  for (var i = 0; i < pcbdata.modules.length; i++) {
    var mod = pcbdata.modules[i];
    var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
    if (!highlight || highlightedModules.includes(i)) {
      drawModule(ctx, layer, scalefactor, mod, padcolor, outlinecolor, highlight, outline);
    }
  }
}

function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
  var ctx = canvas.getContext("2d");
  for (var d of pcbdata[layername][layer]) {
    if (["segment", "arc", "circle", "curve"].includes(d.type)) {
      drawedge(ctx, scalefactor, d, edgeColor);
    } else if (d.type == "polygon") {
      drawPolygonShape(ctx, d, polygonColor);
    } else {
      drawtext(ctx, d, textColor, layer == "B");
    }
  }
}

function drawTracks(canvas, layer, color, highlight) {
  ctx = canvas.getContext("2d");
  ctx.strokeStyle = color;
  ctx.lineCap = "round";
  for(var track of pcbdata.tracks[layer]) {
    if (highlight && highlightedNet != track.net) continue;
    ctx.lineWidth = track.width;
    ctx.beginPath();
    ctx.moveTo(...track.start);
    ctx.lineTo(...track.end);
    ctx.stroke();
  }
}

function drawZones(canvas, layer, color, highlight) {
  ctx = canvas.getContext("2d");
  ctx.strokeStyle = color;
  ctx.fillStyle = color;
  ctx.lineJoin = "round";
  for(var zone of pcbdata.zones[layer]) {
    if (!zone.path2d) {
      zone.path2d = getPolygonsPath(zone);
    }
    if (highlight && highlightedNet != zone.net) continue;
    ctx.lineWidth = zone.width ? zone.width : 0;
    ctx.fill(zone.path2d);
    ctx.stroke(zone.path2d);
  }
}

function clearCanvas(canvas, color = null) {
  var ctx = canvas.getContext("2d");
  ctx.save();
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  if (color) {
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
  } else {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }
  ctx.restore();
}

function drawNets(canvas, layer, highlight) {
  var style = getComputedStyle(topmostdiv);
  if (settings.renderTracks) {
    var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
    drawTracks(canvas, layer, trackColor, highlight);
  }
  if (settings.renderZones) {
    var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
    drawZones(canvas, layer, zoneColor, highlight);
  }
  if (highlight && settings.renderPads) {
    var padColor = style.getPropertyValue('--pad-color-highlight');
    var ctx = canvas.getContext("2d");
    for (var mod of pcbdata.modules) {
      // draw pads
      for (var pad of mod.pads) {
        if (highlightedNet != pad.net) continue;
        if (pad.layers.includes(layer)) {
          drawPad(ctx, pad, padColor, false, true);
        }
      }
    }
  }
}

function drawHighlightsOnLayer(canvasdict, clear = true) {
  if (clear) {
    clearCanvas(canvasdict.highlight);
  }
  if (highlightedModules.length > 0) {
    drawModules(canvasdict.highlight, canvasdict.layer,
      canvasdict.transform.s * canvasdict.transform.zoom, true);
  }
  if (highlightedNet !== null) {
    drawNets(canvasdict.highlight, canvasdict.layer, true);
  }
}

function drawHighlights() {
  drawHighlightsOnLayer(allcanvas.front);
  drawHighlightsOnLayer(allcanvas.back);
}

function drawBackground(canvasdict, clear = true) {
  if (clear) {
    clearCanvas(canvasdict.bg);
    clearCanvas(canvasdict.fab);
    clearCanvas(canvasdict.silk);
  }

  drawNets(canvasdict.bg, canvasdict.layer, false);
  drawModules(canvasdict.bg, canvasdict.layer,
    canvasdict.transform.s * canvasdict.transform.zoom, false);

  drawEdgeCuts(canvasdict.bg, canvasdict.transform.s);

  var style = getComputedStyle(topmostdiv);
  var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
  var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
  var textColor = style.getPropertyValue('--silkscreen-text-color');
  if (settings.renderSilkscreen) {
    drawBgLayer(
      "silkscreen", canvasdict.silk, canvasdict.layer,
      canvasdict.transform.s * canvasdict.transform.zoom,
      edgeColor, polygonColor, textColor);
  }
  edgeColor = style.getPropertyValue('--fabrication-edge-color');
  polygonColor = style.getPropertyValue('--fabrication-polygon-color');
  textColor = style.getPropertyValue('--fabrication-text-color');
  if (settings.renderFabrication) {
    drawBgLayer(
      "fabrication", canvasdict.fab, canvasdict.layer,
      canvasdict.transform.s * canvasdict.transform.zoom,
      edgeColor, polygonColor, textColor);
  }
}

function prepareCanvas(canvas, flip, transform) {
  var ctx = canvas.getContext("2d");
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  var fontsize = 1.55;
  ctx.scale(transform.zoom, transform.zoom);
  ctx.translate(transform.panx, transform.pany);
  if (flip) {
    ctx.scale(-1, 1);
  }
  ctx.translate(transform.x, transform.y);
  ctx.rotate(deg2rad(settings.boardRotation));
  ctx.scale(transform.s, transform.s);
}

function prepareLayer(canvasdict) {
  var flip = (canvasdict.layer == "B");
  for (var c of ["bg", "fab", "silk", "highlight"]) {
    prepareCanvas(canvasdict[c], flip, canvasdict.transform);
  }
}

function rotateVector(v, angle) {
  angle = deg2rad(angle);
  return [
    v[0] * Math.cos(angle) - v[1] * Math.sin(angle),
    v[0] * Math.sin(angle) + v[1] * Math.cos(angle)
  ];
}

function applyRotation(bbox) {
  var corners = [
    [bbox.minx, bbox.miny],
    [bbox.minx, bbox.maxy],
    [bbox.maxx, bbox.miny],
    [bbox.maxx, bbox.maxy],
  ];
  corners = corners.map((v) => rotateVector(v, settings.boardRotation));
  return {
    minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity),
    miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity),
    maxx: corners.reduce((a, v) => Math.max(a, v[0]), -Infinity),
    maxy: corners.reduce((a, v) => Math.max(a, v[1]), -Infinity),
  }
}

function recalcLayerScale(layerdict, width, height) {
  var bbox = applyRotation(pcbdata.edges_bbox);
  var scalefactor = 0.98 * Math.min(
    width / (bbox.maxx - bbox.minx),
    height / (bbox.maxy - bbox.miny)
  );
  if (scalefactor < 0.1) {
    scalefactor = 1;
  }
  layerdict.transform.s = scalefactor;
  var flip = (layerdict.layer == "B");
  if (flip) {
    layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5;
  } else {
    layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor - width) * 0.5;
  }
  layerdict.transform.y = -((bbox.maxy + bbox.miny) * scalefactor - height) * 0.5;
  for (var c of ["bg", "fab", "silk", "highlight"]) {
    canvas = layerdict[c];
    canvas.width = width;
    canvas.height = height;
    canvas.style.width = (width / devicePixelRatio) + "px";
    canvas.style.height = (height / devicePixelRatio) + "px";
  }
}

function redrawCanvas(layerdict) {
  prepareLayer(layerdict);
  drawBackground(layerdict);
  drawHighlightsOnLayer(layerdict);
}

function resizeCanvas(layerdict) {
  var canvasdivid = {
    "F": "frontcanvas",
    "B": "backcanvas"
  } [layerdict.layer];
  var width = document.getElementById(canvasdivid).clientWidth * devicePixelRatio;
  var height = document.getElementById(canvasdivid).clientHeight * devicePixelRatio;
  recalcLayerScale(layerdict, width, height);
  redrawCanvas(layerdict);
}

function resizeAll() {
  resizeCanvas(allcanvas.front);
  resizeCanvas(allcanvas.back);
}

function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) {
  var A = x - x1;
  var B = y - y1;
  var C = x2 - x1;
  var D = y2 - y1;

  var dot = A * C + B * D;
  var len_sq = C * C + D * D;
  var dx, dy;
  if (len_sq == 0) {
    // start and end of the segment coincide
    dx = x - x1;
    dy = y - y1;
  } else {
    var param = dot / len_sq;
    var xx, yy;
    if (param < 0) {
      xx = x1;
      yy = y1;
    } else if (param > 1) {
      xx = x2;
      yy = y2;
    } else {
      xx = x1 + param * C;
      yy = y1 + param * D;
    }
    dx = x - xx;
    dy = y - yy;
  }
  return dx * dx + dy * dy <= d * d;
}

function pointWithinPad(x, y, pad) {
  var v = [x - pad.pos[0], y - pad.pos[1]];
  v = rotateVector(v, -pad.angle);
  if (pad.offset) {
    v[0] -= pad.offset[0];
    v[1] -= pad.offset[1];
  }
  return emptyContext2d.isPointInPath(getCachedPadPath(pad), ...v);
}

function netHitScan(layer, x, y) {
  // Check track segments
  if (settings.renderTracks && pcbdata.tracks) {
    for(var track of pcbdata.tracks[layer]) {
      if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
        return track.net;
      }
    }
  }
  // Check pads
  if (settings.renderPads) {
    for (var mod of pcbdata.modules) {
      for(var pad of mod.pads) {
        if (pad.layers.includes(layer) && pointWithinPad(x, y, pad)) {
          return pad.net;
        }
      }
    }
  }
  return null;
}

function pointWithinModuleBbox(x, y, bbox) {
  var v = [x - bbox.pos[0], y - bbox.pos[1]];
  v = rotateVector(v, bbox.angle);
  return bbox.relpos[0] <= v[0] && v[0] <= bbox.relpos[0] + bbox.size[0] &&
         bbox.relpos[1] <= v[1] && v[1] <= bbox.relpos[1] + bbox.size[1];
}

function bboxHitScan(layer, x, y) {
  var result = [];
  for (var i = 0; i < pcbdata.modules.length; i++) {
    var module = pcbdata.modules[i];
    if (module.layer == layer) {
      if (pointWithinModuleBbox(x, y, module.bbox)) {
        result.push(i);
      }
    }
  }
  return result;
}

function handlePointerDown(e, layerdict) {
  if (e.button != 0) {
    return;
  }
  e.preventDefault();
  e.stopPropagation();

  if (!e.hasOwnProperty("offsetX")) {
    // The polyfill doesn't set this properly
    e.offsetX = e.pageX - e.currentTarget.offsetLeft;
    e.offsetY = e.pageY - e.currentTarget.offsetTop;
  }

  layerdict.pointerStates[e.pointerId] = {
    distanceTravelled: 0,
    lastX: e.offsetX,
    lastY: e.offsetY,
    downTime: Date.now(),
  };
}

function handleMouseClick(e, layerdict) {
  if (!e.hasOwnProperty("offsetX")) {
    // The polyfill doesn't set this properly
    e.offsetX = e.pageX - e.currentTarget.offsetLeft;
    e.offsetY = e.pageY - e.currentTarget.offsetTop;
  }

  var x = e.offsetX;
  var y = e.offsetY;
  var t = layerdict.transform;
  if (layerdict.layer == "B") {
    x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s;
  } else {
    x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s;
  }
  y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s;
  var v = rotateVector([x, y], -settings.boardRotation);
  if ("nets" in pcbdata) {
    var net = netHitScan(layerdict.layer, ...v);
    if (net !== highlightedNet) {
      netClicked(net);
    }
  }
  if (highlightedNet === null) {
    var modules = bboxHitScan(layerdict.layer, ...v);
    if (modules.length > 0) {
      modulesClicked(modules);
    }
  }
}

function handlePointerLeave(e, layerdict) {
  e.preventDefault();
  e.stopPropagation();

  if (!settings.redrawOnDrag) {
    redrawCanvas(layerdict);
  }

  delete layerdict.pointerStates[e.pointerId];
}

function resetTransform(layerdict) {
  layerdict.transform.panx = 0;
  layerdict.transform.pany = 0;
  layerdict.transform.zoom = 1;
  redrawCanvas(layerdict);
}

function handlePointerUp(e, layerdict) {
  if (!e.hasOwnProperty("offsetX")) {
    // The polyfill doesn't set this properly
    e.offsetX = e.pageX - e.currentTarget.offsetLeft;
    e.offsetY = e.pageY - e.currentTarget.offsetTop;
  }

  e.preventDefault();
  e.stopPropagation();

  if (e.button == 2) {
    // Reset pan and zoom on right click.
    resetTransform(layerdict);
    layerdict.anotherPointerTapped = false;
    return;
  }

  // We haven't necessarily had a pointermove event since the interaction started, so make sure we update this now
  var ptr = layerdict.pointerStates[e.pointerId];
  ptr.distanceTravelled += Math.abs(e.offsetX - ptr.lastX) + Math.abs(e.offsetY - ptr.lastY);

  if (e.button == 0 && ptr.distanceTravelled < 10 && Date.now() - ptr.downTime <= 500) {
    if (Object.keys(layerdict.pointerStates).length == 1) {
      if (layerdict.anotherPointerTapped) {
        // This is the second pointer coming off of a two-finger tap
        resetTransform(layerdict);
      } else {
        // This is just a regular tap
        handleMouseClick(e, layerdict);
      }
      layerdict.anotherPointerTapped = false;
    } else {
      // This is the first finger coming off of what could become a two-finger tap
      layerdict.anotherPointerTapped = true;
    }
  } else {
    if (!settings.redrawOnDrag) {
      redrawCanvas(layerdict);
    }
    layerdict.anotherPointerTapped = false;
  }

  delete layerdict.pointerStates[e.pointerId];
}

function handlePointerMove(e, layerdict) {
  if (!layerdict.pointerStates.hasOwnProperty(e.pointerId)) {
    return;
  }
  e.preventDefault();
  e.stopPropagation();

  if (!e.hasOwnProperty("offsetX")) {
    // The polyfill doesn't set this properly
    e.offsetX = e.pageX - e.currentTarget.offsetLeft;
    e.offsetY = e.pageY - e.currentTarget.offsetTop;
  }

  var thisPtr = layerdict.pointerStates[e.pointerId];

  var dx = e.offsetX - thisPtr.lastX;
  var dy = e.offsetY - thisPtr.lastY;

  // If this number is low on pointer up, we count the action as a click
  thisPtr.distanceTravelled += Math.abs(dx) + Math.abs(dy);

  if (Object.keys(layerdict.pointerStates).length == 1) {
    // This is a simple drag
    layerdict.transform.panx += devicePixelRatio * dx / layerdict.transform.zoom;
    layerdict.transform.pany += devicePixelRatio * dy / layerdict.transform.zoom;
  } else if (Object.keys(layerdict.pointerStates).length == 2) {
    var otherPtr = Object.values(layerdict.pointerStates).filter((ptr) => ptr != thisPtr)[0];

    var oldDist = Math.sqrt(Math.pow(thisPtr.lastX - otherPtr.lastX, 2) + Math.pow(thisPtr.lastY - otherPtr.lastY, 2));
    var newDist = Math.sqrt(Math.pow(e.offsetX - otherPtr.lastX, 2)     + Math.pow(e.offsetY - otherPtr.lastY, 2));

    var scaleFactor = newDist/oldDist;

    if (scaleFactor != NaN) {
      layerdict.transform.zoom *= scaleFactor;

      var zoomd = (1 - scaleFactor) / layerdict.transform.zoom;
      layerdict.transform.panx += devicePixelRatio * otherPtr.lastX * zoomd;
      layerdict.transform.pany += devicePixelRatio * otherPtr.lastY * zoomd;
    }
  }

  thisPtr.lastX = e.offsetX;
  thisPtr.lastY = e.offsetY;

  if (settings.redrawOnDrag) {
    redrawCanvas(layerdict);
  }
}

function handleMouseWheel(e, layerdict) {
  e.preventDefault();
  e.stopPropagation();
  var t = layerdict.transform;
  var wheeldelta = e.deltaY;
  if (e.deltaMode == 1) {
    // FF only, scroll by lines
    wheeldelta *= 30;
  } else if (e.deltaMode == 2) {
    wheeldelta *= 300;
  }
  var m = Math.pow(1.1, -wheeldelta / 40);
  // Limit amount of zoom per tick.
  if (m > 2) {
    m = 2;
  } else if (m < 0.5) {
    m = 0.5;
  }
  t.zoom *= m;
  var zoomd = (1 - m) / t.zoom;
  t.panx += devicePixelRatio * e.offsetX * zoomd;
  t.pany += devicePixelRatio * e.offsetY * zoomd;
  redrawCanvas(layerdict);
}

function addMouseHandlers(div, layerdict) {
  div.addEventListener("pointerdown", function(e) {
    handlePointerDown(e, layerdict);
  });
  div.addEventListener("pointermove", function(e) {
    handlePointerMove(e, layerdict);
  });
  div.addEventListener("pointerup", function(e) {
    handlePointerUp(e, layerdict);
  });
  var pointerleave = function(e) {
    handlePointerLeave(e, layerdict);
  }
  div.addEventListener("pointercancel", pointerleave);
  div.addEventListener("pointerleave", pointerleave);
  div.addEventListener("pointerout", pointerleave);

  div.onwheel = function(e) {
    handleMouseWheel(e, layerdict);
  }
  for (var element of [div, layerdict.bg, layerdict.fab, layerdict.silk, layerdict.highlight]) {
    element.addEventListener("contextmenu", function(e) {
      e.preventDefault();
    }, false);
  }
}

function setRedrawOnDrag(value) {
  settings.redrawOnDrag = value;
  writeStorage("redrawOnDrag", value);
}

function setBoardRotation(value) {
  settings.boardRotation = value * 5;
  writeStorage("boardRotation", settings.boardRotation);
  document.getElementById("rotationDegree").textContent = settings.boardRotation;
  resizeAll();
}

function initRender() {
  allcanvas = {
    front: {
      transform: {
        x: 0,
        y: 0,
        s: 1,
        panx: 0,
        pany: 0,
        zoom: 1,
      },
      pointerStates: {},
      anotherPointerTapped: false,
      bg: document.getElementById("F_bg"),
      fab: document.getElementById("F_fab"),
      silk: document.getElementById("F_slk"),
      highlight: document.getElementById("F_hl"),
      layer: "F",
    },
    back: {
      transform: {
        x: 0,
        y: 0,
        s: 1,
        panx: 0,
        pany: 0,
        zoom: 1,
      },
      pointerStates: {},
      anotherPointerTapped: false,
      bg: document.getElementById("B_bg"),
      fab: document.getElementById("B_fab"),
      silk: document.getElementById("B_slk"),
      highlight: document.getElementById("B_hl"),
      layer: "B",
    }
  };
  addMouseHandlers(document.getElementById("frontcanvas"), allcanvas.front);
  addMouseHandlers(document.getElementById("backcanvas"), allcanvas.back);
}

///////////////////////////////////////////////

///////////////////////////////////////////////
/* DOM manipulation and misc code */

var bomsplit;
var canvassplit;
var initDone = false;
var bomSortFunction = null;
var currentSortColumn = null;
var currentSortOrder = null;
var currentHighlightedRowId;
var highlightHandlers = [];
var moduleIndexToHandler = {};
var netsToHandler = {};
var highlightedModules = [];
var highlightedNet = null;
var lastClicked;

function dbg(html) {
  dbgdiv.innerHTML = html;
}

function redrawIfInitDone() {
  if (initDone) {
    redrawCanvas(allcanvas.front);
    redrawCanvas(allcanvas.back);
  }
}

function padsVisible(value) {
  writeStorage("padsVisible", value);
  settings.renderPads = value;
  redrawIfInitDone();
}

function referencesVisible(value) {
  writeStorage("referencesVisible", value);
  settings.renderReferences = value;
  redrawIfInitDone();
}

function valuesVisible(value) {
  writeStorage("valuesVisible", value);
  settings.renderValues = value;
  redrawIfInitDone();
}

function tracksVisible(value) {
  writeStorage("tracksVisible", value);
  settings.renderTracks = value;
  redrawIfInitDone();
}

function zonesVisible(value) {
  writeStorage("zonesVisible", value);
  settings.renderZones = value;
  redrawIfInitDone();
}

function dnpOutline(value) {
  writeStorage("dnpOutline", value);
  settings.renderDnpOutline = value;
  redrawIfInitDone();
}

function setDarkMode(value) {
  if (value) {
    topmostdiv.classList.add("dark");
  } else {
    topmostdiv.classList.remove("dark");
  }
  writeStorage("darkmode", value);
  settings.darkMode = value;
  redrawIfInitDone();
}

function fabricationVisible(value) {
  writeStorage("fabricationVisible", value);
  settings.renderFabrication = value;
  redrawIfInitDone();
}

function silkscreenVisible(value) {
  writeStorage("silkscreenVisible", value);
  settings.renderSilkscreen = value;
  redrawIfInitDone();
}

function setHighlightPin1(value) {
  writeStorage("highlightpin1", value);
  settings.highlightpin1 = value;
  redrawIfInitDone();
}

function getStoredCheckboxRefs(checkbox) {
  function convert(ref) {
    var intref = parseInt(ref);
    if (isNaN(intref)) {
      for (var i = 0; i < pcbdata.modules.length; i++) {
        if (pcbdata.modules[i].ref == ref) {
          return i;
        }
      }
      return -1;
    } else {
      return intref;
    }
  }
  if (!(checkbox in settings.checkboxStoredRefs)) {
    var val = readStorage("checkbox_" + checkbox);
    settings.checkboxStoredRefs[checkbox] = val ? val : "";
  }
  if (!settings.checkboxStoredRefs[checkbox]) {
    return new Set();
  } else {
    return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
  }
}

function getCheckboxState(checkbox, references) {
  var storedRefsSet = getStoredCheckboxRefs(checkbox);
  var currentRefsSet = new Set(references.map(r => r[1]));
  // Get difference of current - stored
  var difference = new Set(currentRefsSet);
  for (ref of storedRefsSet) {
    difference.delete(ref);
  }
  if (difference.size == 0) {
    // All the current refs are stored
    return "checked";
  } else if (difference.size == currentRefsSet.size) {
    // None of the current refs are stored
    return "unchecked";
  } else {
    // Some of the refs are stored
    return "indeterminate";
  }
}

function setBomCheckboxState(checkbox, element, references) {
  var state = getCheckboxState(checkbox, references);
  element.checked = (state == "checked");
  element.indeterminate = (state == "indeterminate");
}

function createCheckboxChangeHandler(checkbox, references) {
  return function() {
    refsSet = getStoredCheckboxRefs(checkbox);
    if (this.checked) {
      // checkbox ticked
      for (var ref of references) {
        refsSet.add(ref[1]);
      }
    } else {
      // checkbox unticked
      for (var ref of references) {
        refsSet.delete(ref[1]);
      }
    }
    settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
    writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
    updateCheckboxStats(checkbox);
  }
}

function clearHighlightedModules() {
  if (currentHighlightedRowId) {
    document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
    currentHighlightedRowId = null;
    highlightedModules = [];
    highlightedNet = null;
  }
}

function createRowHighlightHandler(rowid, refs, net) {
  return function() {
    if (currentHighlightedRowId) {
      if (currentHighlightedRowId == rowid) {
        return;
      }
      document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
    }
    document.getElementById(rowid).classList.add("highlighted");
    currentHighlightedRowId = rowid;
    highlightedModules = refs ? refs.map(r => r[1]) : [];
    highlightedNet = net;
    drawHighlights();
  }
}

function entryMatches(entry) {
  if (settings.bommode == "netlist") {
    // entry is just a net name
    return entry.toLowerCase().indexOf(filter) >= 0;
  }
  // check refs
  for (var ref of entry[3]) {
    if (ref[0].toLowerCase().indexOf(filter) >= 0) {
      return true;
    }
  }
  // check extra fields
  for (var i in config.extra_fields) {
    if (entry[4][i].toLowerCase().indexOf(filter) >= 0) {
      return true;
    }
  }
  // check value
  if (entry[1].toLowerCase().indexOf(filter) >= 0) {
    return true;
  }
  // check footprint
  if (entry[2].toLowerCase().indexOf(filter) >= 0) {
    return true;
  }
  return false;
}

function findRefInEntry(entry) {
  return entry[3].filter(r => r[0].toLowerCase() == reflookup);
}

function highlightFilter(s) {
  if (!filter) {
    return s;
  }
  var parts = s.toLowerCase().split(filter);
  if (parts.length == 1) {
    return s;
  }
  var r = "";
  var pos = 0;
  for (var i in parts) {
    if (i > 0) {
      r += '<mark class="highlight">' +
        s.substring(pos, pos + filter.length) +
        '</mark>';
      pos += filter.length;
    }
    r += s.substring(pos, pos + parts[i].length);
    pos += parts[i].length;
  }
  return r;
}

function checkboxSetUnsetAllHandler(checkboxname) {
  return function() {
    var checkboxnum = 0;
    while (checkboxnum < settings.checkboxes.length &&
      settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
      checkboxnum++;
    }
    if (checkboxnum >= settings.checkboxes.length) {
      return;
    }
    var allset = true;
    var checkbox;
    var row;
    for (row of bombody.childNodes) {
      checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
      if (!checkbox.checked || checkbox.indeterminate) {
        allset = false;
        break;
      }
    }
    for (row of bombody.childNodes) {
      checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
      checkbox.checked = !allset;
      checkbox.indeterminate = false;
      checkbox.onchange();
    }
  }
}

function createColumnHeader(name, cls, comparator) {
  var th = document.createElement("TH");
  th.innerHTML = name;
  th.classList.add(cls);
  th.style.cursor = "pointer";
  var span = document.createElement("SPAN");
  span.classList.add("sortmark");
  span.classList.add("none");
  th.appendChild(span);
  th.onclick = function() {
    if (currentSortColumn && this !== currentSortColumn) {
      // Currently sorted by another column
      currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
      currentSortColumn.childNodes[1].classList.add("none");
      currentSortColumn = null;
      currentSortOrder = null;
    }
    if (currentSortColumn && this === currentSortColumn) {
      // Already sorted by this column
      if (currentSortOrder == "asc") {
        // Sort by this column, descending order
        bomSortFunction = function(a, b) {
          return -comparator(a, b);
        }
        currentSortColumn.childNodes[1].classList.remove("asc");
        currentSortColumn.childNodes[1].classList.add("desc");
        currentSortOrder = "desc";
      } else {
        // Unsort
        bomSortFunction = null;
        currentSortColumn.childNodes[1].classList.remove("desc");
        currentSortColumn.childNodes[1].classList.add("none");
        currentSortColumn = null;
        currentSortOrder = null;
      }
    } else {
      // Sort by this column, ascending order
      bomSortFunction = comparator;
      currentSortColumn = this;
      currentSortColumn.childNodes[1].classList.remove("none");
      currentSortColumn.childNodes[1].classList.add("asc");
      currentSortOrder = "asc";
    }
    populateBomBody();
  }
  return th;
}

function populateBomHeader() {
  while (bomhead.firstChild) {
    bomhead.removeChild(bomhead.firstChild);
  }
  var tr = document.createElement("TR");
  var th = document.createElement("TH");
  th.classList.add("numCol");
  tr.appendChild(th);
  var checkboxCompareClosure = function(checkbox) {
    return (a, b) => {
      var stateA = getCheckboxState(checkbox, a[3]);
      var stateB = getCheckboxState(checkbox, b[3]);
      if (stateA > stateB) return -1;
      if (stateA < stateB) return 1;
      return 0;
    }
  }
  if (settings.bommode == "netlist") {
    th = createColumnHeader("Net name", "bom-netname", (a, b) => {
      if (a > b) return -1;
      if (a < b) return 1;
      return 0;
    });
    tr.appendChild(th);
  } else {
    for (var checkbox of settings.checkboxes) {
      th = createColumnHeader(
        checkbox, "bom-checkbox", checkboxCompareClosure(checkbox));
      th.onclick = fancyDblClickHandler(
        th, th.onclick.bind(th), checkboxSetUnsetAllHandler(checkbox));
      tr.appendChild(th);
    }
    tr.appendChild(createColumnHeader("References", "References", (a, b) => {
      var i = 0;
      while (i < a[3].length && i < b[3].length) {
        if (a[3][i] != b[3][i]) return a[3][i] > b[3][i] ? 1 : -1;
        i++;
      }
      return a[3].length - b[3].length;
    }));
    // Extra fields
    if (config.extra_fields.length > 0) {
      var extraFieldCompareClosure = function(fieldIndex) {
        return (a, b) => {
          var fa = a[4][fieldIndex];
          var fb = b[4][fieldIndex];
          if (fa != fb) return fa > fb ? 1 : -1;
          else return 0;
        }
      }
      for (var i in config.extra_fields) {
        tr.appendChild(createColumnHeader(
          config.extra_fields[i], "extra", extraFieldCompareClosure(i)));
      }
    }
    tr.appendChild(createColumnHeader("Value", "Value", (a, b) => {
      return valueCompare(a[5], b[5], a[1], b[1]);
    }));
    tr.appendChild(createColumnHeader("Footprint", "Footprint", (a, b) => {
      if (a[2] != b[2]) return a[2] > b[2] ? 1 : -1;
      else return 0;
    }));
    if (settings.bommode == "grouped") {
      tr.appendChild(createColumnHeader("Quantity", "Quantity", (a, b) => {
        return a[3].length - b[3].length;
      }));
    }
  }
  bomhead.appendChild(tr);
}

function populateBomBody() {
  while (bom.firstChild) {
    bom.removeChild(bom.firstChild);
  }
  highlightHandlers = [];
  moduleIndexToHandler = {};
  netsToHandler = {};
  currentHighlightedRowId = null;
  var first = true;
  if (settings.bommode == "netlist") {
    bomtable = pcbdata.nets.slice();
  } else {
    switch (settings.canvaslayout) {
      case 'F':
        bomtable = pcbdata.bom.F.slice();
        break;
      case 'FB':
        bomtable = pcbdata.bom.both.slice();
        break;
      case 'B':
        bomtable = pcbdata.bom.B.slice();
        break;
    }
    if (settings.bommode == "ungrouped") {
      // expand bom table
      expandedTable = []
      for (var bomentry of bomtable) {
        for (var ref of bomentry[3]) {
          expandedTable.push([1, bomentry[1], bomentry[2], [ref], bomentry[4], bomentry[5]]);
        }
      }
      bomtable = expandedTable;
    }
  }
  if (bomSortFunction) {
    bomtable = bomtable.sort(bomSortFunction);
  }
  for (var i in bomtable) {
    var bomentry = bomtable[i];
    if (filter && !entryMatches(bomentry)) {
      continue;
    }
    var references = null;
    var netname = null;
    var tr = document.createElement("TR");
    var td = document.createElement("TD");
    var rownum = +i + 1;
    tr.id = "bomrow" + rownum;
    td.textContent = rownum;
    tr.appendChild(td);
    if (settings.bommode == "netlist") {
      netname = bomentry;
      td = document.createElement("TD");
      td.innerHTML = highlightFilter(netname ? netname : "&lt;no net&gt;");
      tr.appendChild(td);
    } else {
      if (reflookup) {
        references = findRefInEntry(bomentry);
        if (references.length == 0) {
          continue;
        }
      } else {
        references = bomentry[3];
      }
      // Checkboxes
      for (var checkbox of settings.checkboxes) {
        if (checkbox) {
          td = document.createElement("TD");
          var input = document.createElement("input");
          input.type = "checkbox";
          input.onchange = createCheckboxChangeHandler(checkbox, references);
          setBomCheckboxState(checkbox, input, references);
          td.appendChild(input);
          tr.appendChild(td);
        }
      }
      // References
      td = document.createElement("TD");
      td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
      tr.appendChild(td);
      // Extra fields
      for (var i in config.extra_fields) {
        td = document.createElement("TD");
        td.innerHTML = highlightFilter(bomentry[4][i]);
        tr.appendChild(td);
      }
      // Value
      td = document.createElement("TD");
      td.innerHTML = highlightFilter(bomentry[1]);
      tr.appendChild(td);
      // Footprint
      td = document.createElement("TD");
      td.innerHTML = highlightFilter(bomentry[2]);
      tr.appendChild(td);
      if (settings.bommode == "grouped") {
        // Quantity
        td = document.createElement("TD");
        td.textContent = bomentry[3].length;
        tr.appendChild(td);
      }
    }
    bom.appendChild(tr);
    var handler = createRowHighlightHandler(tr.id, references, netname);
    tr.onmousemove = handler;
    highlightHandlers.push({
      id: tr.id,
      handler: handler,
    });
    if (references !== null) {
      for (var refIndex of references.map(r => r[1])) {
        moduleIndexToHandler[refIndex] = handler;
      }
    }
    if (netname !== null) {
      netsToHandler[netname] = handler;
    }
    if ((filter || reflookup) && first) {
      handler();
      first = false;
    }
  }
}

function highlightPreviousRow() {
  if (!currentHighlightedRowId) {
    highlightHandlers[highlightHandlers.length - 1].handler();
  } else {
    if (highlightHandlers.length > 1 &&
      highlightHandlers[0].id == currentHighlightedRowId) {
      highlightHandlers[highlightHandlers.length - 1].handler();
    } else {
      for (var i = 0; i < highlightHandlers.length - 1; i++) {
        if (highlightHandlers[i + 1].id == currentHighlightedRowId) {
          highlightHandlers[i].handler();
          break;
        }
      }
    }
  }
  smoothScrollToRow(currentHighlightedRowId);
}

function highlightNextRow() {
  if (!currentHighlightedRowId) {
    highlightHandlers[0].handler();
  } else {
    if (highlightHandlers.length > 1 &&
      highlightHandlers[highlightHandlers.length - 1].id == currentHighlightedRowId) {
      highlightHandlers[0].handler();
    } else {
      for (var i = 1; i < highlightHandlers.length; i++) {
        if (highlightHandlers[i - 1].id == currentHighlightedRowId) {
          highlightHandlers[i].handler();
          break;
        }
      }
    }
  }
  smoothScrollToRow(currentHighlightedRowId);
}

function populateBomTable() {
  populateBomHeader();
  populateBomBody();
}

function modulesClicked(moduleIndexes) {
  var lastClickedIndex = moduleIndexes.indexOf(lastClicked);
  for (var i = 1; i <= moduleIndexes.length; i++) {
    var refIndex = moduleIndexes[(lastClickedIndex + i) % moduleIndexes.length];
    if (refIndex in moduleIndexToHandler) {
      lastClicked = refIndex;
      moduleIndexToHandler[refIndex]();
      smoothScrollToRow(currentHighlightedRowId);
      break;
    }
  }
}

function netClicked(net) {
  if (net in netsToHandler) {
    netsToHandler[net]();
    smoothScrollToRow(currentHighlightedRowId);
  } else {
    clearHighlightedModules();
    highlightedNet = net;
    drawHighlights();
  }
}

function updateFilter(input) {
  filter = input.toLowerCase();
  populateBomTable();
}

function updateRefLookup(input) {
  reflookup = input.toLowerCase();
  populateBomTable();
}

function changeCanvasLayout(layout) {
  document.getElementById("fl-btn").classList.remove("depressed");
  document.getElementById("fb-btn").classList.remove("depressed");
  document.getElementById("bl-btn").classList.remove("depressed");
  switch (layout) {
    case 'F':
      document.getElementById("fl-btn").classList.add("depressed");
      if (settings.bomlayout != "bom-only") {
        canvassplit.collapse(1);
      }
      break;
    case 'B':
      document.getElementById("bl-btn").classList.add("depressed");
      if (settings.bomlayout != "bom-only") {
        canvassplit.collapse(0);
      }
      break;
    default:
      document.getElementById("fb-btn").classList.add("depressed");
      if (settings.bomlayout != "bom-only") {
        canvassplit.setSizes([50, 50]);
      }
  }
  settings.canvaslayout = layout;
  writeStorage("canvaslayout", layout);
  resizeAll();
  changeBomMode(settings.bommode);
}

function populateMetadata() {
  document.getElementById("title").innerHTML = pcbdata.metadata.title;
  document.getElementById("revision").innerHTML = "Rev: " + pcbdata.metadata.revision;
  document.getElementById("company").innerHTML = pcbdata.metadata.company;
  document.getElementById("filedate").innerHTML = pcbdata.metadata.date;
  if (pcbdata.metadata.title != "") {
    document.title = pcbdata.metadata.title + " BOM";
  }
  var fp_f = 0, fp_b = 0, pads_f = 0, pads_b = 0, pads_th = 0;
  for (var i = 0; i < pcbdata.modules.length; i++) {
    if (pcbdata.bom.skipped.includes(i)) continue;
    var mod = pcbdata.modules[i];
    if (mod.layer == "F") {
      fp_f++;
    } else {
      fp_b++;
    }
    for (var pad of mod.pads) {
      if (pad.type == "th") {
        pads_th++;
      } else {
        if (pad.layers.includes("F")) {
          pads_f++;
        }
        if (pad.layers.includes("B")) {
          pads_b++;
        }
      }
    }
  }
  document.getElementById("stats-components-front").innerHTML = fp_f;
  document.getElementById("stats-components-back").innerHTML = fp_b;
  document.getElementById("stats-components-total").innerHTML = fp_f + fp_b;
  document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length;
  document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length;
  document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length;
  document.getElementById("stats-smd-pads-front").innerHTML = pads_f;
  document.getElementById("stats-smd-pads-back").innerHTML = pads_b;
  document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b;
  document.getElementById("stats-th-pads").innerHTML = pads_th;
}

function changeBomLayout(layout) {
  document.getElementById("bom-btn").classList.remove("depressed");
  document.getElementById("lr-btn").classList.remove("depressed");
  document.getElementById("tb-btn").classList.remove("depressed");
  switch (layout) {
    case 'bom-only':
      document.getElementById("bom-btn").classList.add("depressed");
      if (bomsplit) {
        bomsplit.destroy();
        bomsplit = null;
        canvassplit.destroy();
        canvassplit = null;
      }
      document.getElementById("frontcanvas").style.display = "none";
      document.getElementById("backcanvas").style.display = "none";
      document.getElementById("bot").style.height = "";
      break;
    case 'top-bottom':
      document.getElementById("tb-btn").classList.add("depressed");
      document.getElementById("frontcanvas").style.display = "";
      document.getElementById("backcanvas").style.display = "";
      document.getElementById("bot").style.height = "calc(100% - 80px)";
      document.getElementById("bomdiv").classList.remove("split-horizontal");
      document.getElementById("canvasdiv").classList.remove("split-horizontal");
      document.getElementById("frontcanvas").classList.add("split-horizontal");
      document.getElementById("backcanvas").classList.add("split-horizontal");
      if (bomsplit) {
        bomsplit.destroy();
        bomsplit = null;
        canvassplit.destroy();
        canvassplit = null;
      }
      bomsplit = Split(['#bomdiv', '#canvasdiv'], {
        sizes: [50, 50],
        onDragEnd: resizeAll,
        direction: "vertical",
        gutterSize: 5
      });
      canvassplit = Split(['#frontcanvas', '#backcanvas'], {
        sizes: [50, 50],
        gutterSize: 5,
        onDragEnd: resizeAll
      });
      break;
    case 'left-right':
      document.getElementById("lr-btn").classList.add("depressed");
      document.getElementById("frontcanvas").style.display = "";
      document.getElementById("backcanvas").style.display = "";
      document.getElementById("bot").style.height = "calc(100% - 80px)";
      document.getElementById("bomdiv").classList.add("split-horizontal");
      document.getElementById("canvasdiv").classList.add("split-horizontal");
      document.getElementById("frontcanvas").classList.remove("split-horizontal");
      document.getElementById("backcanvas").classList.remove("split-horizontal");
      if (bomsplit) {
        bomsplit.destroy();
        bomsplit = null;
        canvassplit.destroy();
        canvassplit = null;
      }
      bomsplit = Split(['#bomdiv', '#canvasdiv'], {
        sizes: [50, 50],
        onDragEnd: resizeAll,
        gutterSize: 5
      });
      canvassplit = Split(['#frontcanvas', '#backcanvas'], {
        sizes: [50, 50],
        gutterSize: 5,
        direction: "vertical",
        onDragEnd: resizeAll
      });
  }
  settings.bomlayout = layout;
  writeStorage("bomlayout", layout);
  changeCanvasLayout(settings.canvaslayout);
}

function changeBomMode(mode) {
  document.getElementById("bom-grouped-btn").classList.remove("depressed");
  document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
  document.getElementById("bom-netlist-btn").classList.remove("depressed");
  switch (mode) {
    case 'grouped':
      document.getElementById("bom-grouped-btn").classList.add("depressed");
      break;
    case 'ungrouped':
      document.getElementById("bom-ungrouped-btn").classList.add("depressed");
      break;
    case 'netlist':
      document.getElementById("bom-netlist-btn").classList.add("depressed");
  }
  writeStorage("bommode", mode);
  if (mode != settings.bommode) {
    settings.bommode = mode;
    bomSortFunction = null;
    currentSortColumn = null;
    currentSortOrder = null;
    clearHighlightedModules();
  }
  populateBomTable();
}

function focusFilterField() {
  focusInputField(document.getElementById("filter"));
}

function focusRefLookupField() {
  focusInputField(document.getElementById("reflookup"));
}

function toggleBomCheckbox(bomrowid, checkboxnum) {
  if (!bomrowid || checkboxnum > settings.checkboxes.length) {
    return;
  }
  var bomrow = document.getElementById(bomrowid);
  var checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
  checkbox.checked = !checkbox.checked;
  checkbox.indeterminate = false;
  checkbox.onchange();
}

function checkBomCheckbox(bomrowid, checkboxname) {
  var checkboxnum = 0;
  while (checkboxnum < settings.checkboxes.length &&
    settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
    checkboxnum++;
  }
  if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
    return;
  }
  var bomrow = document.getElementById(bomrowid);
  var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
  checkbox.checked = true;
  checkbox.indeterminate = false;
  checkbox.onchange();
}

function setBomCheckboxes(value) {
  writeStorage("bomCheckboxes", value);
  settings.checkboxes = value.split(",").filter((e) => e);
  prepCheckboxes();
  populateBomTable();
}

function prepCheckboxes() {
  var table = document.getElementById("checkbox-stats");
  while (table.childElementCount > 1) {
    table.removeChild(table.lastChild);
  }
  if (settings.checkboxes.length) {
    table.style.display = "";
  } else {
    table.style.display = "none";
  }
  for (var checkbox of settings.checkboxes) {
    var tr = document.createElement("TR");
    var td = document.createElement("TD");
    td.innerHTML = checkbox;
    tr.appendChild(td);
    td = document.createElement("TD");
    td.id = "checkbox-stats-" + checkbox;
    var progressbar = document.createElement("div");
    progressbar.classList.add("bar");
    td.appendChild(progressbar);
    var text = document.createElement("div");
    text.classList.add("text");
    td.appendChild(text);
    tr.appendChild(td);
    table.appendChild(tr);
    updateCheckboxStats(checkbox);
  }
}

function updateCheckboxStats(checkbox) {
  var checked = getStoredCheckboxRefs(checkbox).size;
  var total = pcbdata.modules.length - pcbdata.bom.skipped.length;
  var percent = checked * 100.0 / total;
  var td = document.getElementById("checkbox-stats-" + checkbox);
  td.firstChild.style.width = percent + "%";
  td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
}

document.onkeydown = function(e) {
  switch (e.key) {
    case "n":
      if (document.activeElement.type == "text") {
        return;
      }
      if (currentHighlightedRowId !== null) {
        checkBomCheckbox(currentHighlightedRowId, "placed");
        highlightNextRow();
        e.preventDefault();
      }
      break;
    case "ArrowUp":
      highlightPreviousRow();
      e.preventDefault();
      break;
    case "ArrowDown":
      highlightNextRow();
      e.preventDefault();
      break;
    default:
      break;
  }
  if (e.altKey) {
    switch (e.key) {
      case "f":
        focusFilterField();
        e.preventDefault();
        break;
      case "r":
        focusRefLookupField();
        e.preventDefault();
        break;
      case "z":
        changeBomLayout("bom-only");
        e.preventDefault();
        break;
      case "x":
        changeBomLayout("left-right");
        e.preventDefault();
        break;
      case "c":
        changeBomLayout("top-bottom");
        e.preventDefault();
        break;
      case "v":
        changeCanvasLayout("F");
        e.preventDefault();
        break;
      case "b":
        changeCanvasLayout("FB");
        e.preventDefault();
        break;
      case "n":
        changeCanvasLayout("B");
        e.preventDefault();
        break;
      default:
        break;
    }
    if (e.key >= '1' && e.key <= '9') {
      toggleBomCheckbox(currentHighlightedRowId, parseInt(e.key));
    }
  }
}

function hideNetlistButton() {
  document.getElementById("bom-ungrouped-btn").classList.remove("middle-button");
  document.getElementById("bom-ungrouped-btn").classList.add("right-most-button");
  document.getElementById("bom-netlist-btn").style.display = "none";
}

window.onload = function(e) {
  initUtils();
  initRender();
  initStorage();
  initDefaults();
  cleanGutters();
  populateMetadata();
  dbgdiv = document.getElementById("dbg");
  bom = document.getElementById("bombody");
  bomhead = document.getElementById("bomhead");
  filter = "";
  reflookup = "";
  if (!("nets" in pcbdata)) {
    hideNetlistButton();
  }
  initDone = true;
  prepCheckboxes();
  // Triggers render
  changeBomLayout(settings.bomlayout);
}

window.onresize = resizeAll;
window.matchMedia("print").addListener(resizeAll);

///////////////////////////////////////////////

  </script>
</head>

<body>
<div id="topmostdiv" class="topmostdiv">
  <div id="top">
    <div style="float: right; height: 100%;">
      <div class="hideonprint menu" style="float: right; top: 8px;">
        <button class="menubtn"></button>
        <div class="menu-content">
          <label class="menu-label menu-label-top">
            <input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
            Dark mode
          </label>
          <label class="menu-label">
            <input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
            Show footprint pads
          </label>
          <label class="menu-label" style="width: calc(50% - 18px)">
            <input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
            Fab layer
          </label><!-- This comment eats space! All of it!
          --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
            <input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
            Silkscreen
          </label>
          <label class="menu-label" style="width: calc(50% - 18px)">
            <input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
            References
          </label><!-- This comment eats space! All of it!
          --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
            <input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
            Values
          </label>
          <div id="tracksAndZonesCheckboxes">
            <label class="menu-label" style="width: calc(50% - 18px)">
              <input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
              Tracks
            </label><!-- This comment eats space! All of it!
            --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
              <input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
              Zones
            </label>
          </div>
          <label class="menu-label">
            <input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
            DNP components outlined
          </label>
          <label class="menu-label">
            <input id="highlightpin1Checkbox" type="checkbox" onchange="setHighlightPin1(this.checked)">
            Highlight first pin
          </label>
          <label class="menu-label">
            <input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
            Continuous redraw on drag
          </label>
          <label class="menu-label">
            <span>Board rotation</span>
            <span style="float: right"><span id="rotationDegree">0</span>&#176;</span>
            <input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)">
          </label>
          <label class="menu-label">
            <div style="margin-left: 5px">Bom checkboxes</div>
            <input id="bomCheckboxes" class="menu-textbox" type=text
                   oninput="setBomCheckboxes(this.value)">
          </label>
          <label class="menu-label">
            <span class="shameless-plug">
              <span>Created using</span>
              <a target="blank" href="https://github.com/openscopeproject/InteractiveHtmlBom">InteractiveHtmlBom</a>
            </span>
          </label>
        </div>
      </div>
      <div class="button-container hideonprint"
           style="float: right; position: relative; top: 8px">
        <button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
                title="Front only">F
        </button>
        <button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
                title="Front and Back">FB
        </button>
        <button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
                title="Back only">B
        </button>
      </div>
      <div class="button-container hideonprint"
           style="float: right; position: relative; top: 8px">
        <button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
                title="BOM only"></button>
        <button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
                title="BOM left, drawings right"></button>
        <button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
                title="BOM top, drawings bot"></button>
      </div>
      <div class="button-container hideonprint"
           style="float: right; position: relative; top: 8px">
        <button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
                title="Grouped BOM"></button>
        <button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
                title="Ungrouped BOM"></button>
        <button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
                title="Netlist"></button>
      </div>
      <div class="hideonprint menu" style="float: right; top: 8px;">
        <button class="statsbtn"></button>
        <div class="menu-content">
          <table class="stats">
            <tbody>
              <tr>
                <td width="40%">Board stats</td>
                <td>Front</td>
                <td>Back</td>
                <td>Total</td>
              </tr>
              <tr>
                <td>Components</td>
                <td id="stats-components-front">~</td>
                <td id="stats-components-back">~</td>
                <td id="stats-components-total">~</td>
              </tr>
              <tr>
                <td>Groups</td>
                <td id="stats-groups-front">~</td>
                <td id="stats-groups-back">~</td>
                <td id="stats-groups-total">~</td>
              </tr>
              <tr>
                <td>SMD pads</td>
                <td id="stats-smd-pads-front">~</td>
                <td id="stats-smd-pads-back">~</td>
                <td id="stats-smd-pads-total">~</td>
              </tr>
              <tr>
                <td>TH pads</td>
                <td colspan=3 id="stats-th-pads">~</td>
              </tr>
            </tbody>
          </table>
          <table class="stats">
            <col width="40%"/><col />
            <tbody id="checkbox-stats">
              <tr>
                <td colspan=2 style="border-top: 0">Checkboxes</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
      <div class="hideonprint menu" style="float: right; top: 8px;">
        <button class="iobtn"></button>
        <div class="menu-content">
          <div class="menu-label menu-label-top">
            <div style="margin-left: 5px;">Save board image</div>
            <div class="flexbox">
              <input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
                  style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
              <span>X</span>
              <input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
                  style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
            </div>
            <label>
              <input id="render-save-transparent" type="checkbox">
              Transparent background
            </label>
            <div class="flexbox">
              <button class="savebtn" onclick="saveImage('F')">Front</button>
              <button class="savebtn" onclick="saveImage('B')">Back</button>
            </div>
          </div>
          <div class="menu-label">
            <span style="margin-left: 5px;">Config and checkbox state</span>
            <div class="flexbox">
              <button class="savebtn" onclick="saveSettings()">Export</button>
              <button class="savebtn" onclick="loadSettings()">Import</button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div id="fileinfodiv" style="overflow: auto;">
      <table class="fileinfo">
        <tbody>
          <tr>
            <td id="title" class="title" style="width: 70%">
              Title
            </td>
            <td id="revision" class="title" style="width: 30%">
              Revision
            </td>
          </tr>
          <tr>
            <td id="company">
              Company
            </td>
            <td id="filedate">
              Date
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <div id="bot" class="split" style="height: calc(100% - 80px)">
    <div id="bomdiv" class="split split-horizontal">
      <div style="width: 100%">
        <input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
               oninput="updateRefLookup(this.value)">
        <input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
               oninput="updateFilter(this.value)">
        <div class="button-container hideonprint" style="float: left; margin: 0;">
          <button id="copy" title="Copy bom table to clipboard"
               onclick="copyToClipboard()"></button>
        </div>
      </div>
      <div id="dbg"></div>
      <table class="bom">
        <thead id="bomhead">
        </thead>
        <tbody id="bombody">
        </tbody>
      </table>
    </div>
    <div id="canvasdiv" class="split split-horizontal">
      <div id="frontcanvas" class="split" touch-action="none" style="overflow: hidden">
        <div style="position: relative; width: 100%; height: 100%;">
          <canvas id="F_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
          <canvas id="F_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
          <canvas id="F_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
          <canvas id="F_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
        </div>
      </div>
      <div id="backcanvas" class="split" touch-action="none" style="overflow: hidden">
        <div style="position: relative; width: 100%; height: 100%;">
          <canvas id="B_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
          <canvas id="B_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
          <canvas id="B_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
          <canvas id="B_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
        </div>
      </div>
    </div>
  </div>
</div>
</body>

</html>
